Exemplo n.º 1
0
 public static function create_array($ids)
 {
     global $vbulletin;
     $current_user = new vB_Legacy_CurrentUser();
     $select = array();
     $joins = array();
     $where = array();
     $select[] = "thread.*";
     $where[] = "thread.threadid IN (" . implode(',', array_map('intval', $ids)) . ")";
     // always add the thread preview field to the results, unless it is disabled.
     if ($vbulletin->options['threadpreview'] > 0) {
         $select[] = "post.pagetext AS preview";
         $joins['threadpreview'] = "LEFT JOIN " . TABLE_PREFIX . "post AS post ON(post.postid = thread.firstpostid)";
     } else {
         //being a chicken here and making sure we don't remove the preview item
         //from the array in case it matters
         $select[] = "'' as preview";
     }
     if (!$current_user->isGuest()) {
         //join in thread subscriptions if enabled
         if ($vbulletin->options['threadsubscribed']) {
             $select[] = "subscribethread.subscribethreadid";
             $joins['subscribethread'] = "LEFT JOIN " . TABLE_PREFIX . "subscribethread AS subscribethread ON\r\n\t\t\t\t\tsubscribethread.threadid = thread.threadid AND\r\n\t\t\t\t\tsubscribethread.userid =  " . intval($current_user->getField('userid'));
         }
         if ($vbulletin->options['threadmarking']) {
             $select[] = "threadread.readtime";
             $joins['threadread'] = "LEFT JOIN " . TABLE_PREFIX . "threadread AS threadread ON\r\n\t\t\t\t\tthreadread.threadid = thread.threadid AND\r\n\t\t\t\t\tthreadread.userid =  " . intval($current_user->getField('userid'));
         }
     }
     global $vbulletin;
     $set = $vbulletin->db->query($q = "\r\n\t\t\tSELECT " . implode(",", $select) . "\r\n\t\t\tFROM " . TABLE_PREFIX . "thread AS thread\r\n\t\t\t\t" . implode("\n", $joins) . "\r\n\t\t\tWHERE " . implode(' AND ', $where) . "\r\n\t\t");
     $threads = array();
     while ($threadinfo = $vbulletin->db->fetch_array($set)) {
         $threads[$threadinfo['threadid']] = self::create_from_record($threadinfo);
     }
     return $threads;
 }
Exemplo n.º 2
0
 /**
  * Can the user view the post as a search result
  *
  * @param vB_Legacy_CurrentUser $user
  * @return boolean
  */
 public function can_search($user)
 {
     if ($thread = $this->get_thread() and in_array($thread->get_field('forumid'), $user->getUnsearchableForums())) {
         return false;
     }
     return $this->can_view($user);
 }
Exemplo n.º 3
0
require_once(DIR . '/includes/functions_forumdisplay.php');
require_once(DIR . '/includes/functions_search.php');
//error_reporting(E_ALL);

//new search stuff.
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");

// #######################################################################
// ######################## START MAIN SCRIPT ############################
// #######################################################################

$search_core = vB_Search_Core::get_instance();
$current_user = new vB_Legacy_CurrentUser();

if (!$current_user->hasPermission('forumpermissions', 'cansearch'))
{
	print_no_permission();
}

if (!$vbulletin->options['enablesearches'])
{
	eval(standard_error(fetch_error('searchdisabled')));
}

// #############################################################################
$vbulletin->input->clean_array_gpc('r', array(
	'contenttypeid'  => TYPE_UINT,
	'contenttype'  => TYPE_STR,
Exemplo n.º 4
0
 public function add_advanced_search_filters($criteria, $registry)
 {
     if ($registry->GPC['threadlimit']) {
         $criteria->add_display_strings('forumthreadlimit', vB_Search_Searchtools::getCompareString($registry->GPC['threadless']) . $registry->GPC['threadlimit'] . ' ' . $vbphrase['threads']);
         $op = $registry->GPC['threadless'] ? vB_Search_Core::OP_LT : vB_Search_Core::OP_GT;
         $criteria->add_filter('forumthreadlimit', $op, $registry->GPC['threadlimit'], true);
     }
     if ($registry->GPC['postlimit']) {
         $criteria->add_display_strings('forumthreadlimit', vB_Search_Searchtools::getCompareString($registry->GPC['postless']) . $registry->GPC['postlimit'] . ' ' . $vbphrase['posts']);
         $op = $registry->GPC['postless'] ? vB_Search_Core::OP_LT : vB_Search_Core::OP_GT;
         $criteria->add_filter('forumpostlimit', $op, $registry->GPC['postlimit'], true);
     }
     if ($registry->GPC['forumdateline']) {
         if (is_numeric($registry->GPC['forumdateline'])) {
             $dateline = TIMENOW - $this->forumdateline * 86400;
         } else {
             $current_user = new vB_Legacy_CurrentUser();
             $dateline = $current_user->get_field('lastvisit');
         }
         $op = $registry->GPC['beforeafter'] == 'before' ? vB_Search_Core::OP_LT : vB_Search_Core::OP_GT;
         $criteria->add_filter('forumpostdateline', $op, $dateline, true);
         $this->set_display_date($criteria, $registry->GPC['forumdateline'], $registry->GPC['beforeafter']);
     }
     ($hook = vBulletinHook::fetch_hook('search_advanced_filters')) ? eval($hook) : false;
 }
Exemplo n.º 5
0
    public static function create_array($ids)
    {
        global $vbulletin;
        $current_user = new vB_Legacy_CurrentUser();
        $select = array();
        $joins = array();
        $where = array();
        $threadids = implode(',', array_map('intval', $ids));
        $select[] = "thread.*";
        $where[] = "thread.threadid IN ({$threadids})";
        // always add the thread preview field to the results, unless it is disabled.
        if ($vbulletin->options['threadpreview'] > 0) {
            $select[] = "post.pagetext AS preview";
            $joins['threadpreview'] = "LEFT JOIN " . TABLE_PREFIX . "post AS post ON(post.postid = thread.firstpostid)";
        } else {
            //being a chicken here and making sure we don't remove the preview item
            //from the array in case it matters
            $select[] = "'' as preview";
        }
        if (!$current_user->isGuest()) {
            //join in thread subscriptions if enabled
            if ($vbulletin->options['threadsubscribed']) {
                $select[] = "subscribethread.subscribethreadid";
                $joins['subscribethread'] = "LEFT JOIN " . TABLE_PREFIX . "subscribethread AS subscribethread ON\n\t\t\t\t\tsubscribethread.threadid = thread.threadid AND\n\t\t\t\t\tsubscribethread.userid =  " . intval($current_user->getField('userid'));
            }
            if ($vbulletin->options['threadmarking']) {
                $select[] = "threadread.readtime";
                $joins['threadread'] = "LEFT JOIN " . TABLE_PREFIX . "threadread AS threadread ON\n\t\t\t\t\tthreadread.threadid = thread.threadid AND\n\t\t\t\t\tthreadread.userid =  " . intval($current_user->getField('userid'));
            }
        }
        if ($vbulletin->options['avatarenabled']) {
            $select[] = 'avatar.avatarpath, NOT ISNULL(customavatar.userid) AS hascustomavatar, user.avatarrevision,
						customavatar.dateline AS avatardateline, customavatar.width AS width, customavatar.height AS height,
						customavatar.height_thumb AS height_thumb, customavatar.width_thumb AS width_thumb, customavatar.filedata_thumb,
						first_user.avatarrevision AS first_avatarrevision, first_avatar.avatarpath AS first_avatarpath,
						NOT ISNULL(first_customavatar.userid) AS first_hascustomavatar, first_customavatar.dateline AS first_avatardateline,
						first_customavatar.width AS first_width, first_customavatar.height AS first_height, first_customavatar.height_thumb
						AS first_height_thumb, first_customavatar.width_thumb AS first_width_thumb, first_customavatar.filedata_thumb AS
						first_filedata_thumb';
            $joins[] = 'LEFT JOIN ' . TABLE_PREFIX . 'user AS user ON (user.userid = thread.lastposterid)';
            $joins[] = 'LEFT JOIN ' . TABLE_PREFIX . 'avatar AS avatar ON (avatar.avatarid = user.avatarid)';
            $joins[] = 'LEFT JOIN ' . TABLE_PREFIX . 'customavatar AS customavatar ON (customavatar.userid = user.userid)';
            $joins[] = 'LEFT JOIN ' . TABLE_PREFIX . 'user AS first_user ON (first_user.userid = thread.postuserid)';
            $joins[] = 'LEFT JOIN ' . TABLE_PREFIX . 'avatar AS first_avatar ON (first_avatar.avatarid = first_user.avatarid)';
            $joins[] = 'LEFT JOIN ' . TABLE_PREFIX . 'customavatar AS first_customavatar ON (first_customavatar.userid = first_user.userid)';
        }
        if ($vbulletin->options['showdots']) {
            $select[] = "lastpost.lastposttime";
            $joins['lastpost'] = "LEFT JOIN (\n\t\t\t\tSELECT threadid, MAX(dateline) AS lastposttime\n\t\t\t\tFROM " . TABLE_PREFIX . "post\n\t\t\t\tWHERE threadid IN ({$threadids})\n\t\t\t\t\tAND userid = " . intval($current_user->getField('userid')) . "\n\t\t\t\tGROUP BY threadid\n\t\t\t) AS lastpost ON (lastpost.threadid = thread.threadid)";
        }
        $set = $vbulletin->db->query_read_slave("\n\t\t\tSELECT " . implode(",", $select) . "\n\t\t\tFROM " . TABLE_PREFIX . "thread AS thread\n\t\t\t\t" . implode("\n", $joins) . "\n\t\t\tWHERE " . implode(' AND ', $where) . "\n\t\t");
        $threads = array();
        while ($threadinfo = $vbulletin->db->fetch_array($set)) {
            $threads[$threadinfo['threadid']] = self::create_from_record($threadinfo);
        }
        return $threads;
    }
Exemplo n.º 6
0
	public function checkSaveData($view)
	{
		require_once DIR . '/includes/functions_databuild.php';
		require_once DIR . '/includes/functions.php';
		fetch_phrase_group('cpcms');
		($hook = vBulletinHook::fetch_hook('vbcms_section_save_start')) ? eval($hook) : false;

		// Check if inline form was submitted
		vB::$vbulletin->input->clean_array_gpc('r', array(
			'do' => vB_Input::TYPE_STR
		));

		//let's make sure we use the Post value of do
		vB::$vbulletin->input->clean_array_gpc('p', array(
			'do' => vB_Input::TYPE_STR,
			'per_page' => TYPE_INT,
			'new_parentid' => TYPE_INT,
			'html_title' => TYPE_STR,
			'title' => TYPE_STR,
			'displayorder' => TYPE_INT,
			'content_layout' => TYPE_INT,
			'pagination_links' => TYPE_INT,
			'contentfrom' => TYPE_INT,
			'new_parentid' => TYPE_INT,
			'simple_paging' => TYPE_INT,
			'perpage' => TYPE_INT,
		));

		if (vB::$vbulletin->GPC_exists['new_parentid'] AND intval(vB::$vbulletin->GPC['new_parentid'])
			AND (intval(vB::$vbulletin->GPC['new_parentid'] != $this->content->getParentId())) )
		{
			vBCms_ContentManager::moveSection(array($this->content->getNodeId()), vB::$vbulletin->GPC['new_parentid']);
		}

		if ($_REQUEST['do'] == 'apply' OR $_REQUEST['do'] == 'update' )
		{
			// collect error messages
			$errors = array();

			// create dm
			$dm = $this->content->getDM();
			$this->config = array();

			if (vB::$vbulletin->GPC_exists['perpage']) //This is the number displayed on the edit page
			{
				$current_user = new vB_Legacy_CurrentUser();
				if (!$stored_prefs = $current_user->getSearchPrefs())
				{
					$stored_prefs = array();
				}

				if (vB::$vbulletin->GPC_exists['perpage'] AND intval(vB::$vbulletin->GPC['perpage']))
				{
					$stored_prefs['cmsadmin_showperpage'] = intval(vB::$vbulletin->GPC['perpage']);
					$current_user->saveSearchPrefs($stored_prefs);
				}
			}

			if (vB::$vbulletin->GPC_exists['per_page']) //This is the number of items displayed to the end user in the view
			{
				$this->config['items_perhomepage'] = vB::$vbulletin->GPC['per_page'];
			}

			if (vB::$vbulletin->GPC_exists['displayorder'])
			{
				$this->config['section_priority'] = vB::$vbulletin->GPC['displayorder'];
			}

			if (vB::$vbulletin->GPC_exists['content_layout'])
			{
				$this->config['content_layout'] = vB::$vbulletin->GPC['content_layout'];
			}

			if (vB::$vbulletin->GPC_exists['title'])
			{
				$this->config['title'] = vB::$vbulletin->GPC['title'];
			}

			if (vB::$vbulletin->GPC_exists['pagination_links'])
			{
				$this->config['pagination_links'] = vB::$vbulletin->GPC['pagination_links'];
			}


			if (vB::$vbulletin->GPC_exists['simple_paging'])
			{
				$this->config['simple_paging'] = 1;
			}

			$this->config['contentfrom'] = (vB::$vbulletin->GPC_exists['contentfrom']
				AND (vB::$vbulletin->GPC['contentfrom'] == 1)) ? 1 : 2;

			if (count($this->config))
			{
				$dm->set('config', $this->config);
				$this->content->setConfig($this->config);
			}
			$dm->saveFromForm($this->content->getNodeId());

			if ($dm->hasErrors())
			{
				$fieldnames = array(
					'title' => new vB_Phrase('global', 'title')
				);

				$view->errors = $dm->getErrors(array_keys($fieldnames));
				$view->error_summary = self::getErrorSummary($dm->getErrors(array_keys($fieldnames)), $fieldnames);
				$view->status = $view->error_view->title;
			}
			else
			{
				$view->status = new vB_Phrase('vbcms', 'content_saved');

				// reroute to the section
				$route = new vBCms_Route_Content();
				$route->node = $this->content->getUrlSegment();
				$url = $route->getCurrentUrl();

				($hook = vBulletinHook::fetch_hook('vbcms_section_save_end')) ? eval($hook) : false;
			}

		}
		$this->changed = true;
		($hook = vBulletinHook::fetch_hook('vbcms_section_save_end')) ? eval($hook) : false;
		//invalidate the navigation cache.
		vB_Cache::instance()->event('sections_updated');
		vB_Cache::instance()->event('articles_updated');
		vB_Cache::instance()->event($this->content->getCacheEvents());
		vB_Cache::instance()->event($this->getCleanCacheEvents());
		vB_Cache::instance()->cleanNow();
		$this->content->reset();
	}
Exemplo n.º 7
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;
			}
			//We have a content type and an array of id's. We need to build the result
			//objects.
			$controller = vB_Search_Core::get_instance()->get_search_type_from_id($cache_data['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']);
		}

		//First set the contenttype, if appropriate.
		if (! intval($config['days']))
		{
			$config['days'] = 7;
		}

		if (! intval($config['count']))
		{
			$config['count'] = 10;
		}

		if (isset($config['contenttypeid']) AND $config['contenttypeid'])
		{
			$contenttypeid = $config['contenttypeid'];
			$criteria = $search_core->create_criteria(vB_Search_Core::SEARCH_ADVANCED);
			//It's important to figure whether we need to group or not. We group for blogentries and posts
			$criteria->set_grouped( vB_Search_Core::GROUP_NO);
			$search_type = vB_Search_Core::get_instance()->get_search_type_from_id($contenttypeid);
			$criteria->set_advanced_typeid($contenttypeid);
			$criteria->add_contenttype_filter($contenttypeid);

			//Ugly hack, but we need to do this if the content type is blogentry.
			if (vB_Types::instance()->getContentTypeID('vBBlog_BlogEntry') == $contenttypeid )
			{
				vB::$vbulletin->GPC['ignorecomments'] = true;
			}

		}
		else if ((isset($config['forumchoice']) AND count($config['forumchoice']) AND $config['forumchoice'][0])
			OR (isset($config['prefixchoice']) AND count($config['prefixchoice']) AND $config['prefixchoice'][0]))
		{
			$contenttypeid = vB_Types::instance()->getContentTypeID('vBForum_Post');
			$search_type = vB_Search_Core::get_instance()->get_search_type_from_id($contenttypeid);
			$criteria = $search_core->create_criteria($contenttypeid);
			$criteria->set_advanced_typeid($contenttypeid);
			$criteria->add_contenttype_filter($contenttypeid);
			$criteria->set_grouped(vB_Search_Core::GROUP_NO);
		}
		else if ((isset($config['group']) AND $config['group'] != '')
			OR (isset($config['cat']) AND count($config['cat']) AND $config['cat'][0]))
		{
			//We haven't gotten a specific content type, and we won't work without one,
			// so assume we're showing visitor messages.
			$contenttypeid = vB_Types::instance()->getContentTypeID('vBForum_SocialGroupMessage');
			$search_type = vB_Search_Core::get_instance()->get_search_type_from_id($contenttypeid);
			$criteria = $search_core->create_criteria($contenttypeid);
			$criteria->set_advanced_typeid($contenttypeid);
			$criteria->add_contenttype_filter($contenttypeid);
		}
		else
		{
			return $vbphrase['widget_needs_configuration'];
		}


		//tag applies to several types. Let's do that next.
		if (isset($config['tag']) AND ($config['tag'] != '') )
		{
			$criteria->add_tag_filter($config['tag']);
		}

		//now set the content-type specific items.
		if ((isset($config['forumchoice']) AND count($config['forumchoice']) AND $config['forumchoice'][0])
			 AND $contenttypeid == vB_Types::instance()->getContentTypeID('vBForum_Post'))
		{
			$criteria->add_forumid_filter($config['forumchoice'], $config['childforums']);
		}
		else
		{
			$criteria->add_excludeforumid_filter(vB::$vbulletin->options['vbcmsforumid']);
		}

		if ((isset($config['prefixchoice']) AND count($config['prefixchoice']) AND $config['prefixchoice'][0])
			 AND $contenttypeid == vB_Types::instance()->getContentTypeID('vBForum_Post'))
		{
				$criteria->add_filter('prefix', vB_Search_Core::OP_EQ, $config['prefixchoice'], true);
		}

		if ((isset($config['cat']) AND count($config['cat']) AND $config['cat'][0]) AND $contenttypeid == vB_Types::instance()->getContentTypeID('vBForum_SocialGroup'))
		{
			$criteria->add_filter('sgcategory', vB_Search_Core::OP_EQ, $config['cat'], true);
		}

		if (isset($config['group']) AND ($config['group'] != '') AND $contenttypeid == vB_Types::instance()->getContentTypeID('vBForum_SocialGroupMessage'))
		{
			$criteria->add_filter('socialgroup', vB_Search_Core::OP_EQ, $config['group'], true);
		}
		else if ((isset($config['cat']) AND count($config['cat']) AND $config['cat'][0]) AND $contenttypeid == vB_Types::instance()->getContentTypeID('vBForum_SocialGroupMessage'))
		{
			$criteria->add_filter('sgcategoryid', vB_Search_Core::OP_EQ, $config['cat'], true);
		}

		$search_type->add_advanced_search_filters($criteria, vB::$vbulletin);

		$current_user = new vB_Legacy_CurrentUser();

		$timelimit = TIMENOW - (86400 * $config['days']);
		$criteria->add_date_filter(vB_Search_Core::OP_GT, $timelimit);

		if ($config['username'] AND $config['username'] != '')
		{
			$criteria->add_user_filter($config['username'], true, true);
		}
		else if ($config['friends'])
		{
			$friends = $this->getFriends($current_user->getField('userid'));

			if (count($friends))
			{
				$criteria->add_userid_filter($friends, false);
			}
			else
			{
				return '';
			}
		}

		if ($config['keywords'] AND $config['keywords'] != '')
		{
			$criteria->add_keyword_filter($config['keywords'], false);
		}


		$criteria->set_sort('dateline', 'desc');

		$results = vB_Search_Results::create_from_cache($current_user, $criteria);

		if (!$results)
		{
			$results = vB_Search_Results::create_from_criteria($current_user, $criteria);
		}

		$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('contenttypeid' => $contenttypeid,
			'ids' => $ids, 'criteria' =>$criteria), $this->cache_ttl,
			$this->getCacheEvent());

		return array('results' => $page_results, 'criteria' => $criteria);

	}
Exemplo n.º 8
0
 private function json2criteria(&$json)
 {
     if (is_string($json)) {
         $search_structure = json_decode($json, true);
     } else {
         $search_structure = $json;
     }
     if (empty($search_structure) or !is_array($search_structure)) {
         throw new vB_Exception_Api('invalid_search_syntax', array($json));
     }
     $criteria = new vB_Search_Criteria();
     $def_sort_field = 'created';
     $def_sort_dir = 'DESC';
     $currentUserId = vB::getCurrentSession()->get('userid');
     $criteria->setUser($currentUserId);
     $normalized_criteria = array();
     if (!empty($search_structure['keywords'])) {
         $words = $criteria->add_keyword_filter($search_structure['keywords'], !empty($search_structure['title_only']));
         $def_sort_field = 'lastcontent';
         if (!empty($words)) {
             $normalized_criteria['keywords'] = '';
             $separator = '';
             foreach ($words as $word) {
                 if (!empty($word['joiner'])) {
                     $normalized_criteria['keywords'] .= $separator . strtoupper($word['joiner']);
                     $separator = ' ';
                 }
                 $normalized_criteria['keywords'] .= $separator . $word['word'];
                 $separator = ' ';
             }
             if (!empty($search_structure['title_only'])) {
                 $normalized_criteria['title_only'] = 1;
             }
         } else {
             $normalized_criteria['error'] = 'ignored_search_keywords';
         }
         $ignored_words = $criteria->get_ignored_keywords();
         if (!empty($ignored_words)) {
             $normalized_criteria['ignored_words'] = $ignored_words;
             $normalized_criteria['original_keywords'] = $search_structure['keywords'];
         }
     }
     if (!empty($search_structure['contenttypeid'])) {
         $search_structure['type'] = vB_Types::instance()->getContentTypeClasses($search_structure['contenttypeid']);
         if (count($search_structure['type']) == 1) {
             $search_structure['type'] = array_pop($search_structure['type']);
         }
         unset($search_structure['contenttypeid']);
     }
     if (!empty($search_structure['type'])) {
         $contentypeids = $criteria->add_contenttype_filter($search_structure['type']);
         $normalized_criteria['type'] = $search_structure['type'];
         $pmcontentypeid = vB_Types::instance()->getContentTypeID('vBForum_PrivateMessage');
         if (in_array($pmcontentypeid, $contentypeids)) {
             if (count($contentypeids) == 1) {
                 $search_structure['private_messages_only'] = 1;
             } else {
                 $search_structure['include_private_messages'] = 1;
             }
         }
         $vmcontentypeid = vB_Types::instance()->getContentTypeID('vBForum_VisitorMessage');
         if (in_array($vmcontentypeid, $contentypeids)) {
             if (count($contentypeids) == 1) {
                 $search_structure['visitor_messages_only'] = 1;
             } else {
                 $search_structure['include_visitor_messages'] = 1;
             }
         }
         $photocontentypeid = vB_Api::instanceInternal('contenttype')->fetchContentTypeIdFromClass('Photo');
         if (in_array($photocontentypeid, $contentypeids)) {
             $search_structure['include_attach'] = 1;
         }
     } elseif (empty($search_structure['exclude_type']) or is_string($search_structure['exclude_type']) and $search_structure['exclude_type'] != 'vBForum_PrivateMessage' or is_array($search_structure['exclude_type']) and !in_array('vBForum_PrivateMessage', $search_structure['exclude_type'])) {
         $search_structure['include_private_messages'] = 1;
     } elseif (!empty($search_structure['exclude_type']) and (is_string($search_structure['exclude_type']) and $search_structure['exclude_type'] == 'vBForum_VisitorMessage' or is_array($search_structure['exclude_type']) and in_array('vBForum_VisitorMessage', $search_structure['exclude_type']))) {
         $search_structure['exclude_visitor_messages'] = 1;
     }
     if (empty($search_structure['type']) and empty($search_structure['exclude_visitor_messages']) and (empty($search_structure['exclude_type']) or is_string($search_structure['exclude_type']) and $search_structure['exclude_type'] != 'vBForum_VisitorMessage' or is_array($search_structure['exclude_type']) and !in_array('vBForum_VisitorMessage', $search_structure['exclude_type']))) {
         $search_structure['include_visitor_messages'] = 1;
     }
     // author by username
     if (!empty($search_structure['author'])) {
         //reducing users from array to single
         if (is_array($search_structure['author']) and count($search_structure['author']) == 1) {
             $search_structure['author'] = array_pop($search_structure['author']);
             $search_structure['exactname'] = 1;
         }
         // only one username
         if (is_string($search_structure['author'])) {
             // it's an exact username - no partial match
             if (!empty($search_structure['exactname'])) {
                 $search_structure['author'] = trim($search_structure['author']);
                 switch ($search_structure['author']) {
                     case 'myFriends':
                         $userid = array();
                         if (!empty($currentUserId)) {
                             $userid = vB::getDbAssertor()->getColumn('userlist', 'relationid', array('userid' => $currentUserId, 'friend' => 'yes'), false, 'relationid');
                         }
                         $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $userid, true);
                         break;
                     case 'iFollow':
                         if (empty($search_structure[self::FILTER_FOLLOW])) {
                             $search_structure[self::FILTER_FOLLOW] = self::FILTER_FOLLOWING_USERS;
                         } elseif ($search_structure[self::FILTER_FOLLOW] == self::FILTER_FOLLOWING_CHANNEL) {
                             $search_structure[self::FILTER_FOLLOW] = self::FILTER_FOLLOWING_BOTH;
                         }
                         break;
                     default:
                         $criteria->add_user_filter($search_structure['author'], !empty($search_structure['exactname']));
                         break;
                 }
                 $normalized_criteria['author'] = strtolower($search_structure['author']);
                 $normalized_criteria['exactname'] = 1;
             } elseif (vb_String::vbStrlen($search_structure['author']) >= 3) {
                 $criteria->add_user_filter($search_structure['author'], !empty($search_structure['exactname']));
                 $normalized_criteria['author'] = strtolower($search_structure['author']);
             }
         } elseif (is_array($search_structure['author'])) {
             $user_names = array();
             foreach ($search_structure['author'] as $author) {
                 $author = vB_String::htmlSpecialCharsUni($author);
                 $user = vB_Api::instanceInternal("User")->fetchByUsername($author);
                 $userid = false;
                 if (!empty($user['userid'])) {
                     $user_ids[] = $user['userid'];
                     $user_names[] = $user['username'];
                 }
             }
             if (!empty($user_ids)) {
                 $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $user_ids, true);
             } else {
                 $criteria->add_null_filter('no record matches usernames');
             }
             sort($user_names);
             $normalized_criteria['author'] = $user_names;
         }
     }
     // author by userid
     if (!empty($search_structure['authorid'])) {
         //reducing users from array to single
         if (is_array($search_structure['authorid']) and count($search_structure['authorid']) == 1) {
             $search_structure['authorid'] = array_pop($search_structure['authorid']);
         }
         if (is_numeric($search_structure['authorid'])) {
             if (!empty($search_structure['visitor_messages_only'])) {
                 $criteria->add_filter('visitor_messages_only', vB_Search_Core::OP_EQ, $search_structure['authorid']);
                 $normalized_criteria['visitor_messages_only'] = 1;
             } elseif (!empty($search_structure['include_visitor_messages'])) {
                 $criteria->add_filter('include_visitor_messages', vB_Search_Core::OP_EQ, $search_structure['authorid']);
                 $normalized_criteria['include_visitor_messages'] = 1;
             } else {
                 $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $search_structure['authorid'], true);
             }
             if (!empty($search_structure['exclude_visitor_messages'])) {
                 $criteria->add_filter('exclude_visitor_messages', vB_Search_Core::OP_EQ, $search_structure['authorid']);
                 $normalized_criteria['exclude_visitor_messages'] = 1;
             }
             $normalized_criteria['authorid'] = $search_structure['authorid'];
         } elseif (is_array($search_structure['authorid'])) {
             $user_ids = array();
             foreach ($search_structure['authorid'] as $author) {
                 if (is_numeric($author)) {
                     $user_ids[] = intval($author);
                 }
             }
             $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $user_ids, true);
             $normalized_criteria['authorid'] = sort($user_ids);
         }
     } else {
         if (!empty($search_structure['exclude_visitor_messages'])) {
             $criteria->add_filter('exclude_visitor_messages', vB_Search_Core::OP_EQ, 0);
             $normalized_criteria['exclude_visitor_messages'] = 1;
         }
     }
     // channel owner filter
     if (!empty($search_structure['my_channels'])) {
         $temp = array();
         // restrict 'type' to string 'blog' or 'group', else default to 'blog'
         if (isset($search_structure['my_channels']['type']) and ($search_structure['my_channels']['type'] == 'blog' or $search_structure['my_channels']['type'] == 'group')) {
             $temp['type'] = $search_structure['my_channels']['type'];
         } else {
             $temp['type'] = 'blog';
         }
         $normalized_criteria['my_channels'] = $temp;
         $criteria->add_filter('my_channels', vB_Search_Core::OP_EQ, $temp);
         unset($temp);
     }
     if (!empty($search_structure['private_messages_only'])) {
         $criteria->add_filter('private_messages_only', vB_Search_Core::OP_EQ, $currentUserId);
         $normalized_criteria['private_messages_only'] = 1;
     }
     // visitor message recipient
     if (!empty($search_structure['sentto'])) {
         //reducing users from array to single
         if (is_array($search_structure['sentto']) and count($search_structure['sentto']) == 1) {
             $search_structure['sentto'] = array_pop($search_structure['sentto']);
         }
         if (is_numeric($search_structure['sentto'])) {
             $criteria->add_filter('sentto', vB_Search_Core::OP_EQ, intval($search_structure['sentto']));
             $normalized_criteria['visitor_messages_only'] = 1;
             $normalized_criteria['sentto'] = intval($search_structure['sentto']);
         } elseif (is_array($search_structure['sentto'])) {
             $user_ids = array_map('intval', $search_structure['sentto']);
             sort($user_ids);
             $criteria->add_filter('sentto', vB_Search_Core::OP_EQ, $user_ids);
             $normalized_criteria['visitor_messages_only'] = 1;
             $normalized_criteria['sentto'] = $user_ids;
         }
     }
     if (!empty($search_structure['tag'])) {
         if (is_array($search_structure['tag'])) {
             foreach ($search_structure['tag'] as $index => $tag) {
                 $search_structure['tag'][$index] = vB_String::htmlSpecialCharsUni(trim($tag));
             }
         } else {
             $search_structure['tag'] = vB_String::htmlSpecialCharsUni(trim($search_structure['tag']));
         }
         $existing_tags = $criteria->add_tag_filter($search_structure['tag']);
         $normalized_criteria['tag'] = array_keys($existing_tags);
         vB_Api::instanceInternal('Tags')->logSearchTags($existing_tags);
     }
     if (!empty($search_structure['date'])) {
         if ($search_structure['date'] == self::FILTER_LASTVISIT) {
             $current_user = new vB_Legacy_CurrentUser();
             $dateline = $current_user->get_field('lastvisit');
             if (empty($dateline)) {
                 $dateline = vB::getRequest()->getTimeNow() - 86400 * 14;
             }
             $criteria->add_date_filter(vB_Search_Core::OP_GT, $dateline);
             $normalized_criteria['date'] = self::FILTER_LASTVISIT;
         }
         if ($search_structure['date'] == self::FILTER_TOPICAGE) {
             $age = vB::getDatastore()->getOption('max_age_topic');
             if (intval($age) == 0) {
                 $age = 60;
             }
             $criteria->add_date_filter(vB_Search_Core::OP_GT, vB::getRequest()->getTimeNow() - 86400 * $age);
             $normalized_criteria['date'] = self::FILTER_TOPICAGE;
         }
         if ($search_structure['date'] == self::FILTER_CHANNELAGE) {
             $age = vB::getDatastore()->getOption('max_age_channel');
             if (intval($age) == 0) {
                 $age = 60;
             }
             $criteria->add_date_filter(vB_Search_Core::OP_GT, vB::getRequest()->getTimeNow() - 86400 * $age);
             $normalized_criteria['date'] = self::FILTER_CHANNELAGE;
         }
         // forcing to get the whole date spectrum; activity stream view enforces a date range so this is the workaround
         if (!empty($search_structure['date']) and is_string($search_structure['date']) and $search_structure['date'] == self::FILTER_DATEALL) {
             $criteria->add_date_filter(vB_Search_Core::OP_EQ, self::FILTER_DATEALL);
             $normalized_criteria['date'] = self::FILTER_DATEALL;
         }
         if (is_array($search_structure['date']) and !empty($search_structure['date']['from'])) {
             $dateline = $this->computeDateLine($search_structure['date']['from']);
             if (!empty($dateline)) {
                 $criteria->add_date_filter(vB_Search_Core::OP_GT, $dateline);
                 $normalized_criteria['date']['from'] = $search_structure['date']['from'];
             }
         }
         if (is_array($search_structure['date']) and !empty($search_structure['date']['to'])) {
             $dateline = $this->computeDateLine($search_structure['date']['to'], true);
             if (!empty($dateline)) {
                 $criteria->add_date_filter(vB_Search_Core::OP_LT, $dateline);
                 $normalized_criteria['date']['to'] = $search_structure['date']['to'];
             }
         }
     }
     if (!empty($search_structure['last'])) {
         if (is_array($search_structure['last']) and !empty($search_structure['last']['from'])) {
             $dateline = $this->computeDateLine($search_structure['last']['from']);
             if (!empty($dateline)) {
                 $criteria->add_last_filter(vB_Search_Core::OP_GT, $dateline);
                 $normalized_criteria['last']['from'] = $search_structure['last']['from'];
             }
         }
         if (is_array($search_structure['last']) and !empty($search_structure['last']['to'])) {
             $dateline = $this->computeDateLine($search_structure['last']['to'], true);
             if (!empty($dateline)) {
                 $criteria->add_last_filter(vB_Search_Core::OP_LT, $dateline);
                 $normalized_criteria['last']['to'] = $search_structure['last']['to'];
             }
         }
     }
     if (!empty($search_structure['exclude'])) {
         $criteria->add_exclude_filter($search_structure['exclude']);
         $normalized_criteria['exclude'] = $search_structure['exclude'];
     }
     if (empty($search_structure['sort'])) {
         $search_structure['sort'] = array($def_sort_field => $def_sort_dir);
     }
     if (!is_array($search_structure['sort'])) {
         $sort_dir = $def_sort_dir;
         if (strtolower($search_structure['sort']) == 'title') {
             $sort_dir = 'ASC';
         }
         $search_structure['sort'] = array($search_structure['sort'] => $sort_dir);
     }
     foreach ($search_structure['sort'] as $sort_field => $sort_dir) {
         $criteria->set_sort($sort_field, strtoupper($sort_dir));
     }
     if ($sort_field != $def_sort_field or $sort_dir != $def_sort_dir) {
         $normalized_criteria['sort'] = array($sort_field => strtoupper($sort_dir));
     }
     if (!empty($search_structure['view'])) {
         if ($search_structure['view'] == vB_Api_Search::FILTER_VIEW_CONVERSATION_STREAM and !empty($search_structure['channel'])) {
             $search_structure['depth'] = 2;
             $search_structure['include_starter'] = true;
         } elseif ($search_structure['view'] == vB_Api_Search::FILTER_VIEW_CONVERSATION_THREAD and !empty($search_structure['channel'])) {
             $search_structure['depth'] = 1;
             $search_structure['include_starter'] = true;
         } else {
             $criteria->add_view_filter($search_structure['view']);
             $normalized_criteria['view'] = $search_structure['view'];
         }
     }
     if (!empty($search_structure['starter_only'])) {
         $criteria->add_filter('starter_only', vB_Search_Core::OP_EQ, true);
         $search_structure['include_starter'] = true;
         $normalized_criteria['starter_only'] = 1;
     }
     if (!empty($search_structure['reply_only'])) {
         $criteria->add_filter('reply_only', vB_Search_Core::OP_EQ, true);
         $search_structure['include_starter'] = false;
         $normalized_criteria['reply_only'] = 1;
     }
     if (!empty($search_structure['comment_only'])) {
         $criteria->add_filter('comment_only', vB_Search_Core::OP_EQ, true);
         $search_structure['include_starter'] = false;
         $normalized_criteria['comment_only'] = 1;
     }
     if (!empty($search_structure['channel'])) {
         $criteria->add_channel_filter($search_structure['channel'], empty($search_structure['depth']) ? false : $search_structure['depth'], empty($search_structure['include_starter']) ? false : true, empty($search_structure['depth_exact']) ? false : true);
         $normalized_criteria['channel'] = $search_structure['channel'];
         if (!empty($search_structure['depth'])) {
             $normalized_criteria['depth'] = $search_structure['depth'];
         }
         if (!empty($search_structure['depth_exact'])) {
             $normalized_criteria['depth_exact'] = true;
         }
         if (!empty($search_structure['include_starter'])) {
             $normalized_criteria['include_starter'] = 1;
         }
     }
     if (!empty($search_structure['featured'])) {
         $criteria->add_filter('featured', vB_Search_Core::OP_EQ, $search_structure['featured']);
         $normalized_criteria['featured'] = 1;
     }
     if (!empty($search_structure[self::FILTER_FOLLOW])) {
         if (is_string($search_structure[self::FILTER_FOLLOW]) and !empty($currentUserId)) {
             $criteria->add_follow_filter($search_structure[self::FILTER_FOLLOW], $currentUserId);
             $normalized_criteria[self::FILTER_FOLLOW] = $search_structure[self::FILTER_FOLLOW];
         } elseif (is_array($search_structure[self::FILTER_FOLLOW])) {
             list($type, $userid) = each($search_structure[self::FILTER_FOLLOW]);
             //if ($userid == $currentUserId)
             //{
             $criteria->add_follow_filter($type, $userid);
             $normalized_criteria[self::FILTER_FOLLOW] = $search_structure[self::FILTER_FOLLOW];
             //}
         }
     }
     if (!empty($search_structure['my_following']) and !empty($currentUserId)) {
         $criteria->add_follow_filter(self::FILTER_FOLLOWING_CHANNEL, $currentUserId);
         $normalized_criteria['my_following'] = $search_structure['my_following'];
     }
     if (!empty($search_structure['exclude_type'])) {
         $criteria->add_contenttype_filter($search_structure['exclude_type'], vB_Search_Core::OP_NEQ);
         $normalized_criteria['exclude_type'] = $search_structure['exclude_type'];
     }
     if (!empty($search_structure['sticky_only'])) {
         $criteria->add_filter('sticky', vB_Search_Core::OP_EQ, '1');
         $normalized_criteria['sticky_only'] = 1;
     }
     if (!empty($search_structure['exclude_sticky'])) {
         $criteria->add_filter('sticky', vB_Search_Core::OP_NEQ, '1');
         $normalized_criteria['exclude_sticky'] = 1;
     }
     if (!empty($search_structure['include_sticky'])) {
         $criteria->set_include_sticky();
         $normalized_criteria['include_sticky'] = 1;
     }
     if (empty($search_structure['include_blocked']) or empty($currentUserId) or !vB::getUserContext()->hasPermission('moderatorpermissions', 'canbanusers')) {
         //block people on the global ignore list.
         $globalignore = trim(vB::getDatastore()->getOption('globalignore'));
         if (!empty($globalignore)) {
             $blocked = preg_split('#\\s+#s', $globalignore, -1, PREG_SPLIT_NO_EMPTY);
             //the user can always see their own posts, so if they are in the blocked list we remove them
             if (!empty($currentUserId)) {
                 $bbuserkey = array_search($currentUserId, $blocked);
                 if ($bbuserkey !== FALSE and $bbuserkey !== NULL) {
                     unset($blocked["{$bbuserkey}"]);
                 }
             }
             //Make sure we didn't just empty the list
             if (!empty($blocked)) {
                 $criteria->add_filter('userid', vB_Search_Core::OP_NEQ, $blocked, false, true);
             }
         }
     } elseif (!empty($currentUserId) and vB::getUserContext()->hasPermission('moderatorpermissions', 'canbanusers')) {
         $normalized_criteria['include_blocked'] = 1;
     }
     if (empty($search_structure['include_blocked']) and !empty($currentUserId)) {
         $currentUserInfo = vB_User::fetchUserinfo($currentUserId);
         if (!empty($currentUserInfo['ignorelist'])) {
             $criteria->add_filter('userid', vB_Search_Core::OP_NEQ, explode(' ', $currentUserInfo['ignorelist']), false, true);
         }
     }
     if (!empty($search_structure['ignore_protected'])) {
         $criteria->add_filter('protected', vB_Search_Core::OP_NEQ, '1');
         $normalized_criteria['ignore_protected'] = 1;
     }
     if (!empty($search_structure['deleted_only']) and !empty($currentUserId) and vB::getUserContext()->hasPermission('moderatorpermissions', 'canremoveposts')) {
         $criteria->add_filter('showpublished', vB_Search_Core::OP_EQ, '0');
         $criteria->add_filter('deleteuserid', vB_Search_Core::OP_NEQ, '0');
         $normalized_criteria['deleted_only'] = 1;
     }
     if (!empty($search_structure['exclude_deleted'])) {
         $criteria->add_filter('showpublished', vB_Search_Core::OP_EQ, '1');
         $normalized_criteria['exclude_deleted'] = 1;
     }
     if (empty($search_structure['include_attach'])) {
         $criteria->add_filter('inlist', vB_Search_Core::OP_EQ, 1);
     } else {
         $normalized_criteria['include_attach'] = 1;
     }
     if (!empty($search_structure['unapproved_only']) and !empty($currentUserId) and vB::getUserContext()->hasPermission('moderatorpermissions', 'canmanagethreads')) {
         $criteria->add_filter('approved', vB_Search_Core::OP_NEQ, '1');
         $normalized_criteria['unapproved_only'] = 1;
     }
     if (!empty($search_structure['unread_only']) and !empty($currentUserId) and vB::getDatastore()->getOption('threadmarking') > 0) {
         $criteria->add_filter('marked', vB_Search_Core::OP_EQ, self::FILTER_MARKED_UNREAD);
         $normalized_criteria['unread_only'] = 1;
     }
     if (!empty($search_structure['specific'])) {
         $criteria->add_filter('nodeid', vB_Search_Core::OP_EQ, $search_structure['specific']);
         $normalized_criteria['specific'] = $search_structure['specific'];
     }
     if (!empty($search_structure['prefix'])) {
         $normalized_criteria['prefix'] = $search_structure['prefix'];
         $criteria->add_filter('prefixid', vB_Search_Core::OP_EQ, $search_structure['prefix']);
     }
     if (!empty($search_structure['has_prefix'])) {
         $normalized_criteria['has_prefix'] = 1;
         $criteria->add_filter('prefixid', vB_Search_Core::OP_NEQ, '');
     }
     if (!empty($search_structure['no_prefix'])) {
         $normalized_criteria['no_prefix'] = 0;
         $criteria->add_filter('prefixid', vB_Search_Core::OP_EQ, '');
     }
     // private messages are included by default. Use the exclude_type filter to exlude them
     // they are not included if a specific channel is requested OR looking for visitor messages
     if (!empty($search_structure['include_private_messages']) and empty($normalized_criteria['private_messages_only']) and empty($normalized_criteria['sentto']) and (empty($normalized_criteria['channel']) or is_numeric($normalized_criteria['channel']) and !in_array($normalized_criteria['channel'], array(vB_Channel::MAIN_CHANNEL, vB_Channel::DEFAULT_CHANNEL_PARENT, vB_Channel::PRIVATEMESSAGE_CHANNEL)) or is_array($normalized_criteria['channel']) and count(array_intersect($normalized_criteria['channel'], array(vB_Channel::MAIN_CHANNEL, vB_Channel::DEFAULT_CHANNEL_PARENT, vB_Channel::PRIVATEMESSAGE_CHANNEL))) == 0) and empty($normalized_criteria['my_channels'])) {
         $criteria->add_filter('include_private_messages', vB_Search_Core::OP_EQ, $currentUserId);
     }
     if (!empty($search_structure['nolimit']) and !empty($normalized_criteria['channel']) and (empty($normalized_criteria['view']) or $normalized_criteria['view'] != self::FILTER_VIEW_ACTIVITY) and empty($search_structure['author']) and empty($search_structure['authorid']) and empty($search_structure['keywords']) and empty($search_structure['sentto']) and empty($search_structure['private_messages_only']) and empty($search_structure['tag']) and empty($search_structure['featured']) and empty($search_structure['my_following']) and empty($search_structure['unapproved_only']) and empty($search_structure['unread_only'])) {
         $normalized_criteria['nolimit'] = 1;
         $criteria->setNoLimit();
     }
     // Two pass caching can be disabled by either ignore_cache which
     // also disabled the searchlog table or by specifying 'disable_two_pass'
     // Two pass caching can be forced on when 'ignore_cache' has been called
     // by specifying 'force_two_pass' (for unit testing the two pass cache functionality itself)
     if (!empty($search_structure['ignore_cache']) or self::IGNORE_CACHE) {
         $normalized_criteria['disable_two_pass'] = 1;
         $criteria->setIgnoreCache(true);
     }
     if (!empty($search_structure['disable_two_pass'])) {
         $normalized_criteria['disable_two_pass'] = 1;
     }
     if (!empty($search_structure['force_two_pass']) and !empty($normalized_criteria['disable_two_pass'])) {
         unset($normalized_criteria['disable_two_pass']);
     }
     //checking for a restrictive filter
     if (empty($normalized_criteria['keywords']) and empty($normalized_criteria['authorid']) and empty($normalized_criteria['author']) and empty($normalized_criteria['private_messages_only']) and empty($normalized_criteria['visitor_messages_only']) and empty($normalized_criteria['sentto']) and empty($normalized_criteria['tag']) and (empty($normalized_criteria['date']) or is_string($normalized_criteria['date']) and $normalized_criteria['date'] == self::FILTER_DATEALL) and (empty($normalized_criteria['last']) or is_string($normalized_criteria['last']) and $normalized_criteria['last'] == self::FILTER_DATEALL) and empty($normalized_criteria['channel']) and empty($normalized_criteria['featured']) and empty($normalized_criteria[self::FILTER_FOLLOW]) and empty($normalized_criteria['my_following']) and empty($normalized_criteria['sticky_only']) and empty($normalized_criteria['deleted_only']) and empty($normalized_criteria['unapproved_only']) and empty($normalized_criteria['unread_only']) and empty($normalized_criteria['specific']) and empty($normalized_criteria['prefix']) and empty($normalized_criteria['has_prefix']) and empty($normalized_criteria['no_prefix']) and empty($normalized_criteria['my_channels'])) {
         //temporary solution for VBV-10061
         if ($normalized_criteria['view'] == self::FILTER_VIEW_ACTIVITY) {
             $dateline = $this->computeDateLine(self::FILTER_LASTMONTH);
             if (!empty($dateline)) {
                 $criteria->add_date_filter(vB_Search_Core::OP_GT, $dateline);
             }
         } else {
             throw new vB_Exception_Api('criteria_not_restrictive', array($normalized_criteria));
         }
     }
     $criteria->setJSON($normalized_criteria);
     $json = $normalized_criteria;
     // allow the clients to send custom fields that will be preserved
     if (!empty($search_structure['custom'])) {
         $json['custom'] = $search_structure['custom'];
     }
     return $criteria;
 }