Пример #1
0
	/**
	 * 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);
			}
		}
	}
Пример #2
0
 /**
 * 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;
 }
Пример #3
0
 /**
  * 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));
     }
 }
Пример #4
0
 /**
  * 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);
 }
Пример #5
0
 /**
  * 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);
 }
Пример #6
0
 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);
     }
 }
Пример #7
0
 /**
  * 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);
 }
Пример #8
0
 /**
  * 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();
 }
Пример #9
0
 /**
  * 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;
 }
Пример #10
0
 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;
 }
Пример #11
0
	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;
	}
Пример #12
0
 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()));
 }
Пример #13
0
 /**
  * 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);
     }
 }
Пример #14
0
 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;
 }
Пример #15
0
 /**
  * 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);
 }
Пример #16
0
	public function get_contenttype()
	{
		return vB_Search_Core::get_instance()->get_contenttypeid('vBBlog', 'BlogEntry');
	}
Пример #17
0
 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');
 }
Пример #18
0
	/**
	 * 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'));
		}
	}
Пример #19
0
	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)
	{
Пример #20
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);
	}
Пример #21
0
 /**
  * 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;
 }
Пример #22
0
	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);
	}
Пример #23
0
/**
 * 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());
}
Пример #24
0
 /**
  * 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();
 }
Пример #25
0
	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;
	}
Пример #26
0
	)
	{
		$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.
Пример #27
0
 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;
 }
Пример #28
0
    $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());
    }
Пример #29
0
	public function get_contenttype()
	{
		return vB_Search_Core::get_instance()->get_contenttypeid('vBForum', 'SocialGroup');
	}
Пример #30
0
	/**
	 * 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();
	}