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; }
/** * 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); }
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,
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; }
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; }
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(); }
/** * 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); }
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; }