/** * Index a thread * * By default this will look up all of the posts in a thread and calls the core * indexer for each one * * @param int $id the thread id */ public function index_thread($id) { global $vbulletin; $thread = vB_Legacy_Thread::create_from_id($id); // make sure thread comes from the CMS comment forum if ($thread->get_field('forumid') != $vbulletin->options['vbcmsforumid']) { return; } $set = $vbulletin->db->query_read(" SELECT post.* FROM " . TABLE_PREFIX . "post AS post WHERE threadid = " . intval($id) ); $indexer = vB_Search_Core::get_instance()->get_core_indexer(); while ($row = $vbulletin->db->fetch_array($set)) { $post = vB_Legacy_Post::create_from_record($row, $thread); $fields = $this->post_to_indexfields($post); if ($fields) { $indexer->index($fields); } } }
/** * vb_Search_Indexcontroller_Queue::indexQueue() * * Index an item based on a map of fieldname/value pairs * * @param string $package : the package which we are indexing * @param string $contenttype : text string with the type of content * @param string $operation: the index action, which will vary depending on the action. * usually it will just be "index" * @param data : If we have fourth parameter we take it as an associative array of field values * @return : boolean success indicator */ public static function indexQueue($package, $contenttype, $operation) { $data = array_slice(func_get_args(), 3); global $vbulletin; $db = vB_Search_Core::get_db(); //For now we need to compose an sql query. Parameters are not available. //First make sure we've got good data. If we don't have the three parameters if (isset($package)) { $dbfields['package'] = "'" . $db->escape_string($package) . "'"; } else { return false; } if (isset($contenttype)) { $dbfields['contenttype'] = "'" . $db->escape_string($contenttype) . "'"; } else { return false; } if (isset($operation)) { $dbfields['operation'] = "'" . $db->escape_string($operation) . "'"; } if (!$vbulletin->options['searchqueueupdates']) { // we just call indexNow. It checks for valid data. return vB_Search_Indexcontroller_QueueProcessor::indexNow($package, $contenttype, $operation, $data); } $dbfields['data'] = "'" . $db->escape_string(serialize($data)) . "'"; $sql = "INSERT INTO " . TABLE_PREFIX . "indexqueue (" . implode(', ', array_keys($dbfields)) . ")\n\t\t\tVALUES ( " . implode(', ', $dbfields) . " )"; $db->query_write($sql); return true; }
/** * vBForum_Search_IndexController_VisitorMessage::index() * * @param integer $id : the record id to be indexed */ public function index($id) { global $vbulletin; //we just pull a record from the database. if ($rst = $vbulletin->db->query_read("SELECT visitormessage.* FROM " . TABLE_PREFIX . "visitormessage AS visitormessage WHERE vmid = {$id}") and $row = $vbulletin->db->fetch_array($rst)) { vB_Search_Core::get_instance()->get_core_indexer()->index($this->recordToIndexfields($row)); } }
/** * Delete "group message" (blog entry). * * Due to stupid schema design, indexed data placed in `blog_text` * table. But we receive ID from `blog` table. Should remap it, * prior to place to queue * * @param int $id */ public function delete($id) { $blog_text_id = $this->_get_blog_text_id($id); if (!$blog_text_id) { return false; } $indexer = vB_Search_Core::get_instance()->get_core_indexer(); return $indexer->delete($this->get_contenttypeid(), $blog_text_id); }
/** * Enter description here... * */ static function init() { //register implementation objects with the search system. $search = vB_Search_Core::get_instance(); $search->register_core_indexer(new vBDBSearch_Indexer()); $search->register_index_controller('vBForum', 'Post', new vBDBSearch_PostIndexController()); $__vBDBSearch_CoreSearchController = new vBDBSearch_CoreSearchController(); $search->register_default_controller($__vBDBSearch_CoreSearchController); // $search->register_search_controller('vBForum', 'Post',$__vBDBSearch_CoreSearchController); }
public function index_id_range($start, $finish) { global $vbulletin; $indexer = vB_Search_Core::get_instance()->get_core_indexer(); $set = $vbulletin->db->query_read_slave($q = $this->make_query("forum.forumid BETWEEN " . intval($start) . " AND " . intval($finish))); while ($row = $vbulletin->db->fetch_array($set)) { $fields = $this->record_to_indexfields($row); $indexer->index($fields); } }
/** * Index group message range * * @param int $start * @param int $end */ public function index_id_range($start, $end) { global $vbulletin; $set = $vbulletin->db->query($this->get_query("m.gmid >= " . intval($start) . " AND m.gmid <= " . intval($end))); $indexer = vB_Search_Core::get_instance()->get_core_indexer(); while ($row = $vbulletin->db->fetch_array($set)) { $indexer->index($this->record_to_indexfields($row)); } $vbulletin->db->free_result($set); }
/** * Mandatory to overwrite for init specific search components * */ static function init() { //register implementation objects with the search system. $search = vB_Search_Core::get_instance(); $search->register_core_indexer(new vBSphinxSearch_Indexer()); $search->register_index_controller('vBForum', 'Post', new vBSphinxSearch_Search_IndexController_Post()); $search->register_index_controller('vBBlog', 'BlogComment', new vBSphinxSearch_Search_IndexController_BlogComment()); $search->register_index_controller('vBBlog', 'BlogEntry', new vBSphinxSearch_Search_IndexController_BlogEntry()); $search->register_index_controller('vBForum', 'SocialGroupMessage', new vBSphinxSearch_Search_IndexController_SocialGroupMessage()); $__vBSphinxSearch_CoreSearchController = new vBSphinxSearch_CoreSearchController(); $search->register_default_controller($__vBSphinxSearch_CoreSearchController); self::_init_index_map(); }
/** * Returns the singleton instance for the search core * * @return vB_Search_Core */ public static function get_instance() { if (is_null(self::$instance)) { self::$instance = new vB_Search_Core(); //initialize the search implementation global $vbulletin; if (!empty($vbulletin->options['searchimplementation'])) { call_user_func(array($vbulletin->options['searchimplementation'], 'init')); } // self::$instance->register_search_controller('vb', 'Tag', new vb_Search_SearchController_Tag()); } return self::$instance; }
public function get_results($user, $criteria) { global $vbulletin; $db = $vbulletin->db; $range_filters = $criteria->get_range_filters(); //get thread/post results. $lastpost_where = array(); $post_lastpost_where = array(); if (!empty($range_filters['markinglimit'][0])) { $cutoff = $range_filters['markinglimit'][0]; $marking_join = "\n\t\t\t\tLEFT JOIN " . TABLE_PREFIX . "discussionread AS discussionread ON\n\t\t\t\t\t(discussionread.discussionid = discussion.discussionid AND discussionread.userid = " . $vbulletin->userinfo['userid'] . ")\n\t\t\t"; $lastpost_where[] = "discussion.lastpost > IF(discussionread.readtime IS NULL,\n\t\t\t\t{$cutoff}, discussionread.readtime)"; $lastpost_where[] = "discussion.lastpost > {$cutoff}"; $post_lastpost_where[] = "groupmessage.dateline > IF(discussionread.readtime IS NULL,\n\t\t\t\t{$cutoff}, discussionread.readtime)"; $post_lastpost_where[] = "groupmessage.dateline > {$cutoff}"; } else { //get date cut -- but only if we're not using the threadmarking filter if (isset($range_filters['datecut'])) { //ignore any upper limit $datecut = $range_filters['datecut'][0]; } else { return $results; } $marking_join = ''; $lastpost_where[] = "discussion.lastpost >= {$datecut}"; $post_lastpost_where[] = "groupmessage.dateline >= {$datecut}"; } $this->process_orderby($criteria); if ($criteria->get_grouped() == vB_Search_Core::GROUP_NO) { $where = array_merge($lastpost_where, $post_lastpost_where); $contenttypeid = vB_Search_Core::get_instance()->get_contenttypeid('vBForum', 'SocialGroupMessage'); $set = $db->query_read_slave("\n\t\t\t\tSELECT groupmessage.gmid, discussion.discussionid\n\t\t\t\tFROM " . TABLE_PREFIX . "groupmessage AS groupmessage\n\t\t\t\tINNER JOIN " . TABLE_PREFIX . "discussion AS discussion ON\n\t\t\t\t\t(discussion.discussionid = groupmessage.discussionid)\n\t\t\t\t{$marking_join}\n\t\t\t\t" . implode("\n", $this->orderby_join) . "\n\t\t\t\tWHERE " . implode(' AND ', $where) . "\n\t\t\t\tORDER BY {$this->orderby}\n\t\t\t\tLIMIT " . intval($vbulletin->options['maxresults'])); while ($row = $db->fetch_array($set)) { $results[] = array($contenttypeid, $row['gmid'], $row['discussionid']); } } else { $contenttypeid = vB_Search_Core::get_instance()->get_contenttypeid('vBForum', 'SocialGroupDiscussion'); $set = $db->query_read_slave("\n\t\t\t\tSELECT discussion.discussionid\n\t\t\t\tFROM " . TABLE_PREFIX . "discussion AS discussion\n\t\t\t\t{$marking_join}\n\t\t\t\t" . implode("\n", $this->orderby_join) . "\n\t\t\t\tWHERE " . implode(' AND ', $lastpost_where) . "\n\t\t\t\tORDER BY {$this->orderby}\n\t\t\t\tLIMIT " . intval($vbulletin->options['maxresults'])); while ($row = $db->fetch_array($set)) { $results[] = array($contenttypeid, $row['discussionid'], $row['discussionid']); } } return $results; }
public function get_results($user, $criteria) { global $vbulletin; $db = $vbulletin->db; $range_filters = $criteria->get_range_filters(); //$equals_filters = $criteria->get_equals_filters(); //$notequals_filter = $criteria->get_equals_filters(); $results = array(); //get date cut -- no marking, just use the datecut. if (isset($range_filters['datecut'])) { //ignore any upper limit $datecut = $range_filters['datecut'][0]; } else { return $results; } $this->process_orderby($criteria); $contenttypeid = vB_Search_Core::get_instance()->get_contenttypeid('vBForum', 'Event'); $set = $db->query_read_slave($q = " SELECT event.eventid FROM " . TABLE_PREFIX . "event AS event " . implode(" ", $this->joins) . " WHERE event.dateline >= $datecut ORDER BY {$this->orderby} LIMIT " . intval($vbulletin->options['maxresults']) ); while ($row = $db->fetch_array($set)) { $results[] = array($contenttypeid, $row['eventid'], $row['eventid']); } return $results; }
public function output() { global $vbulletin, $db; $vbulletin->input->clean_array_gpc('r', array('userids' => TYPE_STR, 'contenttypeids' => TYPE_STR)); $vbulletin->GPC['userids'] = convert_urlencoded_unicode($vbulletin->GPC['userids']); $userids = $vbulletin->GPC['userids']; $vbulletin->GPC['contenttypeids'] = convert_urlencoded_unicode($vbulletin->GPC['contenttypeids']); $contenttypeids = $vbulletin->GPC['contenttypeids']; require_once DIR . "/vb/search/core.php"; require_once DIR . "/vb/legacy/currentuser.php"; require_once DIR . "/vb/search/resultsview.php"; require_once DIR . "/vb/search/searchtools.php"; $search_core = vB_Search_Core::get_instance(); $current_user = new vB_Legacy_CurrentUser(); if (!$vbulletin->options['enablesearches']) { return $this->error('searchdisabled'); } $criteria = $search_core->create_criteria(vB_Search_Core::SEARCH_ADVANCED); $userids_a = explode(',', $userids); $contenttypeids_a = explode(',', $contenttypeids); if (empty($userids_a)) { return $this->error('invalidid'); } $criteria->add_userid_filter($userids_a, vB_Search_Core::GROUP_NO); if (!empty($contenttypeids_a)) { $criteria->add_contenttype_filter($contenttypeids_a); } $results = null; if (!($vbulletin->debug or $vbulletin->GPC_exists['nocache'] and $vbulletin->GPC['nocache'])) { $results = vB_Search_Results::create_from_cache($current_user, $criteria); } if (!$results) { $results = vB_Search_Results::create_from_criteria($current_user, $criteria); } return array("response" => array("errormessage" => "search"), "show" => array("searchid" => $results->get_searchid())); }
/** * Delete a range of items * * @param int $start * @param int $end */ public function delete_id_range($start, $end) { $indexer = vB_Search_Core::get_instance()->get_core_indexer(); for ($i = $start; $i <= $end; $i++) { $indexer->delete($id); } }
private function get_groups($types) { //no types filters if (!$types) { return array(); } //sort types into group by default/item by default buckets $search = vB_Search_Core::get_instance(); $group_types = array(); $item_types = array(); foreach ($types as $typeid) { $type = $search->get_search_type_from_id($typeid); if ($type->can_group()) { $group_types[] = $type->get_groupcontenttypeid(); } else { $group_types[] = $typeid; } } return $group_types; }
/** * We just pass this to the core indexer, which knows how to do this. */ public function merge_group($oldid, $newid) { $indexer = vB_Search_Core::get_instance()->get_core_indexer(); $indexer->merge_group($this->groupcontenttypeid, $oldid, $newid); }
public function get_contenttype() { return vB_Search_Core::get_instance()->get_contenttypeid('vBBlog', 'BlogEntry'); }
public function __construct() { $this->groupcontenttypeid = vB_Search_Core::get_instance()->get_contenttypeid('vBBlog', 'BlogEntry'); $this->contenttypeid = vB_Search_Core::get_instance()->get_contenttypeid('vBBlog', 'BlogComment'); }
/** * Removes content from the indes. */ protected function deleteSearchContent() { if (!$type_info = vB_Search_Core::get_instance()->get_indexed_types($this->item->getContentTypeId())) { //$this->item->getId() (returns the contentid) reflects the value prior to saving anything. //this means that on first save it will be 0 because the content record hasn't been set yet. vB_Search_Indexcontroller_Queue::indexQueue($this->item->getPackage(), $this->item->getClass(), 'delete', $this->getField('contentid')); } }
print_table_header($vbphrase['add_missing_thread_keywords']); print_input_row($vbphrase['number_of_threads_to_process_per_cycle'], 'perpage', 1000); print_submit_row($vbphrase['add_keywords']); print_form_header('misc', 'lostusers'); print_table_header($vbphrase['fix_broken_user_profiles']); print_description_row($vbphrase['finds_users_without_complete_entries']); print_submit_row($vbphrase['fix_broken_user_profiles']); print_form_header('misc', 'doindextypes'); print_table_header($vbphrase['rebuild_search_index'], 2, 0); print_description_row(construct_phrase($vbphrase['note_reindexing_empty_indexes_x'], $vbulletin->session->vars['sessionurl'])); // Get the current types require_once(DIR . '/vb/search/core.php'); $indexer = vB_Search_Core::get_instance(); //don't use array_merge, it will (incorrectly) assume that the keys are index values //instead of meaningful numeric keys and renumber them. $types = array ( 0 => $vbphrase['all']) + vB_Search_Searchtools::get_type_options(); print_select_row($vbphrase['search_content_type_to_index'], 'indextypes', $types); print_input_row($vbphrase['search_items_batch'], 'perpage', 250); print_input_row($vbphrase['search_start_item_id'], 'startat', 0); print_input_row($vbphrase['search_items_to_process'], 'doprocess', 0); print_yes_no_row($vbphrase['include_automatic_javascript_redirect'], 'autoredirect', 1); print_description_row($vbphrase['note_server_intensive']); print_submit_row($vbphrase['rebuild_search_index']); if ($vbulletin->options['cachemaxage'] > 0) {
/** * This sets up the search parameters, gets the query results, * and renders them * * @param array $config * @return string */ private function getResults($config) { include_once DIR . '/includes/functions_misc.php'; $search_core = vB_Search_Core::get_instance(); //first see if we can get cached results $hashkey = $this->getHash(); $cache_data = vB_Cache::instance()->read($hashkey, false, false); if ($cache_data) { //If there are no id's, we're done. if (empty($cache_data['ids'])) { return false; } $controller = vB_Search_Core::get_instance()->get_search_type_from_id($config['contenttypeid']); if (method_exists($controller, 'create_array')) { $results = $controller->create_array($cache_data['ids']); } else if(method_exists($controller, 'create_item')) { $results = array(); foreach ($cache_data['ids'] as $resultid) { $result = $controller->create_item($resultid); if ($result) { $results[] = $result; } } } else { return false; } return array('results' => $results, 'criteria' => $cache_data['criteria']); } $rst = vB::$vbulletin->db->query_read("SELECT relationid FROM " . TABLE_PREFIX . "userlist WHERE friend='yes' AND userid = " . vB::$vbulletin->userinfo['userid'] ); if (!$rst) { return false; } $userids = array(); while($row = vB::$vbulletin->db->fetch_row($rst)) { $userids[] = $row[0]; } //If there are no friends there's no friend information. if (! count($userids)) { return ''; } if ($config['contenttypeid'] == null) { $config['contenttypeid']= array(); } else if (!is_array($config['contenttypeid'])) { $config['contenttypeid'] = array($config['contenttypeid']); } if (!count($userids)) { new vB_Phrase('global', 'your_friends_list_is_empty'); } $criteria = vB_Search_Core::get_instance()->create_criteria(vB_Search_Core::SEARCH_ADVANCED); $criteria->add_contenttype_filter($config['contenttypeid']); $criteria->set_advanced_typeid($contenttypeid); $criteria->add_userid_filter($userids, false); $criteria->set_grouped(vB_Search_Core::GROUP_NO); $timelimit = TIMENOW - (86400 * $config['days']); $criteria->add_date_filter(vB_Search_Core::OP_GT, $timelimit); $criteria->set_sort('dateline', 'desc'); $current_user = new vB_Legacy_CurrentUser(); $results = vB_Search_Results::create_from_cache($current_user, $criteria); if (!$results) { $results = vB_Search_Results::create_from_criteria($current_user, $criteria); } if (empty($results)) { return false; } $page_results = $results->get_page(1, $config['count'], 1); //prepare types for render $items_by_type = array(); foreach ($page_results as $item) { $typeid = $item->get_contenttype(); if ($typeid) { $items_by_type[$typeid][] = $item; $ids[] = $item->get_id(); } } foreach ($items_by_type as $contenttype => $items) { $type = vB_Search_Core::get_instance()->get_search_type_from_id($contenttype); $type->prepare_render($results->get_user(), $items); } vB_Cache::instance()->write($hashkey, array('ids' => $ids, 'criteria' =>$criteria), $this->cache_ttl, 'widget_config_' . $this->widget->getId()); return array('results' => $page_results, 'criteria' => $criteria); }
/** * Deletes a thread * * @param boolean Whether to consider updating post counts, regardless of forum's settings * @param boolean Whether to physically remove the thread from the database * @param array Array of information for a soft delete * @param boolean Whether to add an entry to the moderator log * * @return mixed The number of affected rows */ function delete($countposts = true, $physicaldel = true, $delinfo = NULL, $dolog = true) { if ($threadid = $this->existing['threadid']) { require_once DIR . '/includes/functions_databuild.php'; require_once DIR . "/vb/search/core.php"; ($hook = vBulletinHook::fetch_hook('threaddata_delete')) ? eval($hook) : false; // Search index maintenance if ($physicaldel) { require_once DIR . '/includes/class_taggablecontent.php'; $content = vB_Taggable_Content_Item::create($this->registry, "vBForum_Thread", $threadid); $content->delete_tag_attachments(); //don't queue this, it needs to run before the thread records are deleted. $indexcontroller = vB_Search_Core::get_instance()->get_index_controller('vBForum', 'Post'); $indexcontroller->delete_thread($threadid); } // note: the skip_moderator_log is the inverse of the $dolog argument return delete_thread($threadid, $countposts, $physicaldel, $delinfo, $this->info['skip_moderator_log'] !== null ? !$this->info['skip_moderator_log'] : $dolog, $this->existing); } return false; }
private function render_searchbits($page) { //until we manage to figure out how to handle this global $show; $show['inlinemod'] = false; //prepare types for render $items_by_type = array(); foreach ($page as $item) { $typeid = $item->get_contenttype(); if ($typeid) { $items_by_type[$typeid][] = $item; } } $headinclude_extra = array(); $inline_mod_type = false; $inline_mod_set = false; foreach ($items_by_type as $contenttype => $items) { $type = vB_Search_Core::get_instance()->get_search_type_from_id($contenttype); $type->prepare_render($this->results->get_user(), $items); $headinclude_extra[] = $type->additional_header_text(); //If the type supports inline mod operations *and* we haven't seen another //type that does, select it as the inline mod type. If we have seen another, //then select nothing. Right now we can't easily support inline mod for multiple //types on a single result set. // //The previous logic handled this by not allowing inline mod on *any* mixed result set. //This caused problems with the "get new threads" because we also display (in some cases) //annoucements on that result set. Announcements do not have inline mod, so they don't //really conflict and not allowing inline mod on those results bugs people // //We still exclude common searches (below) to avoid confusing people about why some resultsets //allow inline mod and others don't. It is now safe for the system to remove that restriction //if we decide that allowing inline mod where we can on common searchs outweighs the confusion //caused by it. if ($type->get_inlinemod_type()) { if(!$inline_mod_set) { $inline_mod_type = $type; $inline_mod_set = true; } else { $inline_mod_type = false; } } } $criteria = $this->results->get_criteria(); if (!$criteria->is_common() AND $inline_mod_type) { $options = $inline_mod_type->get_inlinemod_options(); if ($options) { $show['inlinemod'] = true; $this->template->register('mod_options', $this->render_mod_options($options)); $this->template->register('mod_type', $inline_mod_type->get_inlinemod_type()); $this->template->register('mod_action', $inline_mod_type->get_inlinemod_action()); $this->template->register('url', SCRIPTPATH); } } //perform render $searchbits = ''; foreach ($page as $item) { $searchbits .= $item->render($this->results->get_user(), $this->results->get_criteria()); } $this->template->register('headinclude_extra', implode("\n", $headinclude_extra)); $this->template->register('searchbits', $searchbits); }
/** * Display the main search form. * * @param vB_Legacy_Current_User $user The current user for the board. * @param array $globals The array of "global" GPC items and their type defaults * @param array $navbits The navbit array * @param array $errors A list of errors to display, used for redisplaying the form on error * @param array $searchterms A map of form fields posted by the user. Used to propogate the * the form when processing fails. */ function do_intro($user, $globals, $navbits, $search_type, $errors = array(), $searchterms = array()) { global $vbulletin, $vbphrase, $prefs, $searchforumids, $show; if ($vbulletin->GPC['search_type'] OR intval($vbulletin->GPC['searchthreadid']) OR (isset($vbulletin->GPC['searchfromtype']) and strlen($vbulletin->GPC['searchfromtype']) > 6)) { $template = vB_Template::create('search_common_select_type'); } else { $template = vB_Template::create('search_common'); // we only need the list of content types if we're doing the generic $template->register('type_options', vB_Search_Searchtools::get_type_options()); if (!$prefs['type']) $prefs['type'] = array(); $template->register('selectedtypes', $prefs['type']); } search_intro_register_prefs($template, $prefs); vB_Search_Searchtools::searchIntroRegisterHumanVerify($template); //actually render any errors. search_intro_register_errors($template, $errors); $show['errors'] = !empty($errors); $show['tag_option'] = $vbulletin->options['threadtagging']; //check to see if we have a preferred type $defaulttype = null; if ($prefs['type']) { if (is_array($prefs['type'])) { $defaulttype = $prefs['type'][0]; } else { $defaulttype = $prefs['type']; } } if ($vbulletin->GPC['contenttypeid']) { $defaulttype = $vbulletin->GPC['contenttypeid']; } //If we have nothing else, let's show Posts if ($defaulttype == null) { $defaulttype = vB_Search_Core::get_instance()->get_contenttypeid('vBForum', 'Post'); } //If we have the common type, set to the default if ($search_type instanceof vBForum_Search_Type_Common) { unset($search_type); $search_type = vb_Search_Core::get_instance()->get_search_type_from_id($defaulttype); $prefs = vB_Search_Searchtools::searchIntroFetchPrefs($user, $defaulttype); } if ($vbulletin->GPC['search_type'] ) { $template->register('input_search_types', vB_Search_Searchtools::listSearchable('vb_search_params', 'search.php', $prefs, $defaulttype)); if (intval($vbulletin->GPC['contenttypeid']) OR $defaulttype) { $template->register('search_ui', $search_type->listUi($prefs, intval($vbulletin->GPC['contenttypeid']) ? $vbulletin->GPC['contenttypeid'] : $defaulttype)); } } else if (isset($vbulletin->GPC['searchfromtype']) AND strlen($vbulletin->GPC['searchfromtype']) > 6) { $template->register('input_search_types', vB_Search_Searchtools::listSearchable('vb_search_params', 'search.php', $prefs, $defaulttype)); $search_type = explode(':', $vbulletin->GPC['searchfromtype'], 2); if (count($search_type) == 2) { $search_type = vb_Search_Core::get_instance()->get_search_type($search_type[0], $search_type[1]); } else if (intval($vbulletin->GPC['contenttypeid'])) { $search_type = vb_Search_Core::get_instance()->get_search_type_from_id($vbulletin->GPC['contenttypeid']); } if (isset($search_type)) { $template->register('search_ui', $search_type->listUi($prefs, $search_type->get_contenttypeid())); } } $template->register('sessionhash', $sessionhash); search_intro_register_tagcloud($template); if ($vbulletin->debug) { $show['nocache'] = true; } // unlink the 'search' part of the navbits array_pop($navbits); $navbits[''] = $vbphrase['advanced_search']; ($hook = vBulletinHook::fetch_hook('search_intro')) ? eval($hook) : false; //finish off search ($hook = vBulletinHook::fetch_hook('search_complete')) ? eval($hook) : false; $template->register('show', $show); $template->register('navbar', render_navbar_template(construct_navbits($navbits))); $template->register_page_templates(); print_output($template->render()); }
/** * vBForum_Search_Type_Forum::listUi() * This prepares the HTML for the user to search for forums * * @param [type] $prefs the array of user preferences * @param [type] $contenttypeid added for PHP 5.4 strict standards compliance * @param [type] $registers added for PHP 5.4 strict standards compliance * @param [type] $template_name added for PHP 5.4 strict standards compliance * @return $html: complete html for the search elements */ public function listUi($prefs = null, $contenttypeid = null, $registers = null, $template_name = null) { global $vbulletin, $show; $template = vB_Template::create('search_input_forum'); $template->register('securitytoken', $vbulletin->userinfo['securitytoken']); $template->register('contenttypeid', vB_Search_Core::get_instance()->get_contenttypeid('vBForum', 'Forum')); $template->register('show', $show); $this->setPrefs($template, $prefs, array('select' => array('titleonly', 'threadless', 'forumdateline', 'beforeafter', 'postless', 'sortby'), 'cb' => array('nocache'), 'value' => array('query', 'threadlimit', 'postlimit'))); vB_Search_Searchtools::searchIntroRegisterHumanVerify($template); ($hook = vBulletinHook::fetch_hook('search_listui_complete')) ? eval($hook) : false; return $template->render(); }
public function get_results($user, $criteria) { global $vbulletin; $db = $vbulletin->db; $range_filters = $criteria->get_range_filters(); $equals_filters = $criteria->get_equals_filters(); $notequals_filter = $criteria->get_notequals_filters(); //handle forums if (isset($equals_filters['forumid'])) { $forumids = $equals_filters['forumid']; } else { $forumids = array_keys($vbulletin->forumcache); } $excluded_forumids = array(); if (isset($notequals_filter['forumid'])) { $excluded_forumids = $notequals_filter['forumid']; } $forumids = array_diff($forumids, $excluded_forumids, $user->getUnsearchableForums()); $results = array(); if (empty($forumids)) { return $results; } //get announcements if (!$user->isGuest()) { $contenttypeid = vB_Search_Core::get_instance()->get_contenttypeid('vBForum', 'Announcement'); $announcements = array(); $basetime = TIMENOW; $mindate = $basetime - 2592000; // 30 days $announcements = $db->query_read_slave(" SELECT announcement.announcementid FROM " . TABLE_PREFIX . "announcement AS announcement LEFT JOIN " . TABLE_PREFIX . "announcementread AS ar ON (announcement.announcementid = ar.announcementid AND ar.userid = " . $user->get_field('userid') . ") WHERE ISNULL(ar.userid) AND startdate < $basetime AND startdate > $mindate AND enddate > $basetime AND forumid IN(-1, " . implode(', ', $forumids) . ") "); while ($row = $db->fetch_array($announcements)) { $results[] = array($contenttypeid, $row['announcementid'], $row['announcementid']); } } //get thread/post results. if (!empty($range_filters['markinglimit'][0])) { $cutoff = $range_filters['markinglimit'][0]; $marking_join = " LEFT JOIN " . TABLE_PREFIX . "threadread AS threadread ON (threadread.threadid = thread.threadid AND threadread.userid = " . $vbulletin->userinfo['userid'] . ") INNER JOIN " . TABLE_PREFIX . "forum AS forum ON (forum.forumid = thread.forumid) LEFT JOIN " . TABLE_PREFIX . "forumread AS forumread ON (forumread.forumid = forum.forumid AND forumread.userid = " . $vbulletin->userinfo['userid'] . ") "; $lastpost_where = " AND thread.lastpost > IF(threadread.readtime IS NULL, $cutoff, threadread.readtime) AND thread.lastpost > IF(forumread.readtime IS NULL, $cutoff, forumread.readtime) AND thread.lastpost > $cutoff "; $post_lastpost_where = " AND post.dateline > IF(threadread.readtime IS NULL, $cutoff, threadread.readtime) AND post.dateline > IF(forumread.readtime IS NULL, $cutoff, forumread.readtime) AND post.dateline > $cutoff "; } else { //get date cut -- but only if we're not using the threadmarking filter if (isset($range_filters['datecut'])) { //ignore any upper limit $datecut = $range_filters['datecut'][0]; } else { return $results; } $marking_join = ''; $lastpost_where = "AND thread.lastpost >= $datecut"; $post_lastpost_where = "AND post.dateline >= $datecut"; } $orderby = $this->get_orderby($criteria); //This doesn't actually work -- removing. //even though showresults would filter thread.visible=0, thread.visible remains in these 2 queries //so that the 4 part index on thread can be used. if ($criteria->get_grouped() == vB_Search_Core::GROUP_NO) { $contenttypeid = vB_Search_Core::get_instance()->get_contenttypeid('vBForum', 'Post'); $posts = $db->query_read_slave($q = " SELECT post.postid, post.threadid FROM " . TABLE_PREFIX . "post AS post INNER JOIN " . TABLE_PREFIX . "thread AS thread ON (thread.threadid = post.threadid) $marking_join WHERE thread.forumid IN(" . implode(', ', $forumids) . ") $lastpost_where $post_lastpost_where ORDER BY $orderby LIMIT " . intval($vbulletin->options['maxresults']) ); while ($post = $db->fetch_array($posts)) { $results[] = array($contenttypeid, $post['postid'], $post['threadid']); } } else { $contenttypeid = vB_Search_Core::get_instance()->get_contenttypeid('vBForum', 'Thread'); $threads = $db->query_read_slave($q = " SELECT thread.threadid FROM " . TABLE_PREFIX . "thread AS thread $marking_join WHERE thread.forumid IN(" . implode(', ', $forumids) . ") $lastpost_where AND thread.open <> 10 ORDER BY $orderby LIMIT " . intval($vbulletin->options['maxresults']) ); while ($thread = $db->fetch_array($threads)) { $results[] = array($contenttypeid, $thread['threadid'], $thread['threadid']); } } return $results; }
) { $threadtitle = convert_urlencoded_unicode($vbulletin->GPC['title']); $threaddata =& datamanager_init('Thread', $vbulletin, ERRTYPE_SILENT, 'threadpost'); $threaddata->set_existing($threadinfo); if (!can_moderate($threadinfo['forumid'])) { $threaddata->set_info('skip_moderator_log', true); } $threaddata->set('title', $threadtitle); if ($vbulletin->options['similarthreadsearch']) { require_once(DIR . '/vb/search/core.php'); $searchcontroller = vB_Search_Core::get_instance()->get_search_controller(); $similarthreads = $searchcontroller->get_similar_threads($threadtitle, $threadinfo['threadid']); $threaddata->set('similar', implode(',', $similarthreads)); } $getfirstpost = $db->query_first(" SELECT post.* FROM " . TABLE_PREFIX . "post AS post WHERE threadid = $threadinfo[threadid] ORDER BY dateline LIMIT 1 "); if ($threaddata->save()) { // Reindex first post to set up title properly.
public function getSearchResults($params, $db, $check_only = false) { if ($check_only) { return !empty($params['criteria']); } //No cleaning done we only expect the criteria object $this->db = $db; $criteria =& $params['criteria']; $cacheKey = $params['cacheKey']; $this->filters = array('make_equals_filter' => $criteria->get_equals_filters(), 'make_notequals_filter' => $criteria->get_notequals_filters(), 'make_range_filter' => $criteria->get_range_filters()); $this->process_sort($criteria); $this->process_keywords_filters($criteria); if (!empty($this->filters['make_equals_filter']['view'])) { $this->process_view_filters($this->filters['make_equals_filter']['view']); unset($this->filters['make_equals_filter']['view']); } if (!empty($this->filters['make_equals_filter']['follow'])) { $this->process_follow_filters($this->filters['make_equals_filter']['follow'], $criteria); unset($this->filters['make_equals_filter']['follow']); } // channel if (!empty($this->filters['make_equals_filter']['my_channels'])) { $this->process_my_channels_filter($this->filters['make_equals_filter']['my_channels']); unset($this->filters['make_equals_filter']['my_channels']); } //handle equals filters $this->process_filters($criteria, 'make_equals_filter', $db, $cacheKey ? true : false); //handle notequals filters $this->process_filters($criteria, 'make_notequals_filter', $db, $cacheKey ? true : false); //handle range filters $this->process_filters($criteria, 'make_range_filter', $db, $cacheKey ? true : false); $query_joins = ""; if (count($this->join)) { $query_joins = implode(" \n\t\t\t\t", $this->join) . " "; } if (!$this->done_permission_check) { $permflags = $this->getNodePermTerms($cacheKey ? true : false); if (strpos($query_joins, 'AS starter') !== false and !empty($permflags['joins']['starter'])) { //we don't need the starter join. We already have that. unset($permflags['joins']['starter']); } if (!empty($permflags['joins'])) { $query_joins .= implode("\n", $permflags['joins']) . "\n"; } } else { $permflags = array('joins' => false, 'where' => false); } $query_where = ""; if (count($this->where)) { $query_where = "WHERE " . implode(" AND \n\t\t\t\t", $this->where); } else { if (!empty($permflags['where'])) { $query_where = " WHERE "; } } $query_where .= $permflags['where'] . "\n"; $query_limit = false; if (!$criteria->getNoLimit()) { $maxresults = vB::getDatastore()->getOption('maxresults'); $maxresults = $maxresults > 0 ? $maxresults : 0; if (!empty($maxresults)) { $query_limit = "LIMIT " . $maxresults; } } $query_what = $this->what; // Add starter info to result set so that we know what to remove for the second pass. if ($cacheKey) { $userdata = vB::getUserContext()->getAllChannelAccess(); if (!empty($userdata['selfonly'])) { $query_what .= ", starter.parentid, starter.userid"; if (strpos($query_joins, 'node AS starter') === false) { $query_joins .= "\nLEFT JOIN " . TABLE_PREFIX . "node AS starter ON starter.nodeid = IF(node.starter = 0, node.nodeid, node.starter)\n"; } } } $query_order = false; $ordercriteria = array(); $union_what = array($query_what); $union_order = array(); if ($criteria->get_include_sticky()) { if (!empty($this->join['closure'])) { $ordercriteria[] = 'closure.depth ASC'; } $ordercriteria[] = 'node.sticky DESC'; $union_what[] = 'node.sticky'; $union_order[] = 'sticky DESC'; } if ($criteria->getIncludeStarter()) { $ordercriteria[] = 'isstarter DESC'; $query_what .= ', IF(node.nodeid = node.starter, 1, 0) as isstarter'; $union_what[] = 'IF(node.nodeid = node.starter, 1, 0) as isstarter'; $union_order[] = 'isstarter DESC'; } foreach ($this->sort as $field => $dir) { //fall back to default search when no table is joined in that contains score fields if ($field == 'rank' and strpos($query_joins, 'temp_search') === false and strpos($query_joins, 'searchtowords_') === false) { $field = 'node.created'; } if ($field != 'rank') { $ordercriteria[] = $field . " " . $dir; $field_pieces = explode('.', $field); $union_what[] = $field; $union_order[] = array_pop($field_pieces) . " " . $dir; } else { //we need to use the temporary table to compute the final score if (!empty($this->join['temp_search']) and strpos($this->join['temp_search'], 'temp_search AS temp_search')) { $scorefield = "(\n\t\t\t\t\t\tscore *\n\t\t\t\t\t\t(words_nr / (words_nr + " . $this->occurance_factor . ")) *\n\t\t\t\t\t\tGREATEST(1, 5 - ((UNIX_TIMESTAMP() - node.created)/" . $this->date_factor . ")) *\n\t\t\t\t\t\tIF(is_title > 0 , " . $this->title_boost . ", 1) / GREATEST(\n\t\t\t\t\t\t\t(4 * (words_nr - 1) / distance) + 1\n\t\t\t\t\t\t\t, 1)\n\t\t\t\t\t)"; } else { $scorefield = "(\n\t\t\t\t\tscore *\n\t\t\t\t\tGREATEST(1, 5 - ((UNIX_TIMESTAMP() - node.created)/" . $this->date_factor . ")) *\n\t\t\t\t\tIF(is_title > 0 , " . $this->title_boost . ", 1))"; } $ordercriteria[] = $scorefield . $dir; $union_what[] = $scorefield . ' AS rank'; $union_order[] = 'rank ' . $dir; } } // Adding to be always ordered by nodeid in the end. See VBV-4898 $ordercriteria[] = "node.nodeid ASC"; $union_what[] = 'node.nodeid AS nodeid2'; $union_order[] = 'nodeid2 ASC'; // we need to use union in some case to be able to take advantage of the table indexes if (!empty($this->union_condition)) { $unions = array(); $counter = 0; foreach ($this->union_condition as $conditions) { $qjoins = $query_joins; // we need to duplicate the temp_search table because in mysql you can have only one instance of a temp table in query if ($counter > 0 and strpos($query_joins, 'temp_search AS temp_search') !== false) { $tablename = "temp_search{$counter}"; if ($this->db->query_first("SHOW TABLES LIKE '" . TABLE_PREFIX . "{$tablename}'")) { $this->db->query_write($query = "TRUNCATE TABLE " . TABLE_PREFIX . $tablename); } else { $this->db->query_write($query = "CREATE TABLE " . TABLE_PREFIX . "{$tablename} LIKE " . TABLE_PREFIX . "temp_search"); } $this->db->query_write($query = "INSERT INTO " . TABLE_PREFIX . "{$tablename} SELECT * FROM " . TABLE_PREFIX . "temp_search"); $qjoins = str_replace('temp_search AS temp_search', "{$tablename} AS temp_search", $query_joins); } $unions[] = "\n\t\t\t(\n\t\t\t\tSELECT " . implode(", ", $union_what) . "\n\t\t\t\tFROM " . TABLE_PREFIX . $this->from . "\n\t\t\t\t{$qjoins}\n\t\t\t\t" . $query_where . "\t\t\t\tAND " . implode(" AND \n\t\t\t\t", $conditions) . "\n\t\t\t)"; $counter++; } $query = implode("\n\t\t\tUNION", $unions) . "\n\t\t\t" . "ORDER BY " . implode(',', $union_order); } else { $query = "\n\t\t\tSELECT {$query_what}\n\t\t\tFROM " . TABLE_PREFIX . $this->from . "\n\t\t\t{$query_joins}\n\t\t\t{$query_where}\n\t\t\tORDER BY " . implode(',', $ordercriteria); } $query .= "\n\t\t\t{$query_limit}\n\t\t\t" . "\n/**" . __FUNCTION__ . (defined('THIS_SCRIPT') ? '- ' . THIS_SCRIPT : '') . "**/"; $resultclass = 'vB_dB_' . $this->db_type . '_Result'; $config = vB::getConfig(); if (!empty($config['Misc']['debug_sql']) or self::DEBUG) { echo "{$query};\n"; } $post_processors = $criteria->get_post_processors(); if (empty($post_processors)) { $res = array(); $results = new $resultclass($db, $query); if ($cacheKey) { if ($results and $results->valid()) { foreach ($results as $item) { $res[$item['nodeid']] = $item; } } if (!empty($this->filters['make_equals_filter']['channelid'])) { $moreres = vB_Search_Core::saveSecondPassResults($res, $cacheKey, $this->filters['make_equals_filter']['channelid']); } else { $moreres = vB_Search_Core::saveSecondPassResults($res, $cacheKey); } $obj = new ArrayObject($moreres); return $obj->getIterator(); } else { return $results; } } $resultset = new $resultclass($db, $query); foreach ($post_processors as $post_processor) { // get the node ids from the current $resultset $results = array(); foreach ($resultset as $result) { $results[] = $result['nodeid']; } // nothing else to process if (empty($results)) { break; } // create new $resultset based on those node ids $resultset = vB::getDbAssertor()->assertQuery('vBDBSearch:' . $post_processor, array('nodeids' => $results, 'criteria' => $criteria)); } return $resultset; }
$navbits = construct_navbits(array('' => $vbphrase['tags'])); $navbar = render_navbar_template($navbits); ($hook = vBulletinHook::fetch_hook('tags_cloud_complete')) ? eval($hook) : false; $templater = vB_Template::create('tag_cloud_page'); $templater->register_page_templates(); $templater->register('navbar', $navbar); $templater->register('tag_cloud', $tag_cloud); print_output($templater->render()); } // ####################################################################### if ($_REQUEST['do'] == 'tag') { $vbulletin->input->clean_array_gpc('r', array('tag' => TYPE_NOHTML, 'pagenumber' => TYPE_UINT, 'perpage' => TYPE_UINT)); if (!$vbulletin->GPC['tag']) { standard_error(fetch_error('invalidid', $vbphrase['tag'], $vbulletin->options['contactuslink'])); } $search_core = vB_Search_Core::get_instance(); $current_user = new vB_Legacy_CurrentUser(); $criteria = $search_core->create_criteria(vB_Search_Core::SEARCH_TAG); $criteria->add_tag_filter($vbulletin->GPC['tag']); $errors = $criteria->get_errors(); if ($errors) { standard_error(fetch_error($errors[0])); } $results = null; $searchstart = microtime(); if (!($vbulletin->GPC_exists['nocache'] and $vbulletin->GPC['nocache'])) { $results = vB_Search_Results::create_from_cache($current_user, $criteria); } if (!$results) { $results = vB_Search_Results::create_from_criteria($current_user, $criteria, $search_core->get_tag_search_controller()); }
public function get_contenttype() { return vB_Search_Core::get_instance()->get_contenttypeid('vBForum', 'SocialGroup'); }
/** * vBForum_Search_Type_VisitorMessage::listUi() * This function composes the html to display the user interface for this * search type * * @param mixed $prefs : the array of user preferences * @param mixed $contenttypeid : the content type for which we are going to * search * @param array registers : any additional elements to be registered. These are * just passed to the template * @param string $template_name : name of the template to use for display. We have * a default template. * @param boolean $groupable : a flag to tell whether the interface should display * grouping option(s). * @return $html: complete html for the search elements */ public function listUi($prefs = null, $contenttypeid = null, $registers = null, $template_name = null) { global $vbulletin, $vbphrase; if (! isset($template_name)) { $template_name = 'search_input_visitormessage'; } if (! isset($contenttypeid)) { $contenttypeid = vB_Search_Core::get_instance()->get_contenttypeid('vBForum', 'VisitorMessage'); } $template = vB_Template::create($template_name); $template->register('securitytoken', $vbulletin->userinfo['securitytoken']); $template->register('class', $this->get_display_name()); $template->register('contenttypeid',$contenttypeid); $prefsettings = array( 'select'=> array('searchdate', 'beforeafter', 'starteronly', 'sortby'), 'cb' => array('nocache', 'exactname'), 'value' => array('query', 'searchuser')); $this->setPrefs($template, $prefs, $prefsettings); vB_Search_Searchtools::searchIntroRegisterHumanVerify($template); if (isset($registers) and is_array($registers) ) { foreach($registers as $key => $value) { $template->register($key, htmlspecialchars_uni($value)); } } return $template->render(); }