protected function process_sort(vB_Search_Criteria &$criteria)
 {
     $sort_array = $criteria->get_sort();
     $this->sort = array();
     $sort_map = array('user' => 'authorname', 'author' => 'authorname', 'publishdate' => 'publishdate', 'created' => 'created', 'started' => 'created', 'last_post' => 'lastcontent', 'lastcontent' => 'lastcontent', 'title' => 'title', 'textcount' => 'textcount', 'replies' => 'textcount', 'displayorder' => 'displayorder', 'rank' => 'score', 'relevance' => 'score', 'votes' => 'votes');
     foreach ($sort_array as $sort => $direction) {
         $direction = strtoupper($direction);
         if (!in_array($direction, array('ASC', 'DESC'))) {
             $direction = 'ASC';
         }
         // use the starter's title
         if ($sort == 'title') {
             $this->join['starter'] = "LEFT JOIN " . TABLE_PREFIX . "node AS starter ON starter.nodeid = IF(node.starter = 0, node.nodeid, node.starter)";
             $this->sort['starter.title'] = $direction;
             continue;
         }
         // if we don't have a sort, or we have an unrecognized sort type default to relevance descending
         if (!$sort or !isset($sort_map[$sort])) {
             $sort = 'relevance';
             $direction = 'DESC';
         }
         //look for a core sort option
         if (isset($sort_map[$sort])) {
             $sort_field = $sort_map[$sort];
             // process rank sortings
             if ($sort_field == 'score') {
                 $sort_field = 'rank';
             } else {
                 $sort_field = "node.{$sort_field}";
             }
             $this->sort[$sort_field] = $direction;
         }
     }
 }
 /**
  * Get the search query string in the mysql full text format
  *
  * Built to produce the same search strings as the search.php file.
  * The natural language hack is from search.php
  *
  * @param vB_Legacy_Current_User $user user requesting the search
  * @param vB_Search_Criteria $criteria search criteria to process
  */
 protected function get_search_text($user, $criteria)
 {
     //	If the user doesn't have permission to search full text boolean mode,
     // use natural language mode.
     if ($user->hasPermission('genericpermissions', 'cansearchft_bool')) {
         $words = $criteria->get_keywords();
         $search_text = "";
         $word_count = 0;
         foreach ($words as $word_item) {
             $word_count++;
             //The value of the first term is ambiguous.  If the second term is
             //an "or" both the the first and second terms should be treated as
             //ors.  If the second term is an "and" or "not" then the first term
             //should be an and.
             if ($word_count == 2 and $word_item['joiner'] != 'OR') {
                 $search_text = "+{$search_text}";
             }
             $word = $word_item['word'];
             switch ($word_item['joiner']) {
                 case 'OR':
                     // OR is no operator
                     $search_text .= " {$word}";
                     break;
                 case 'NOT':
                     $search_text .= " -{$word}";
                     break;
                 case 'AND':
                     // if we didn't have a joiner, default to and
                 // if we didn't have a joiner, default to and
                 default:
                     if ($search_text) {
                         $search_text .= " +{$word}";
                     } else {
                         //if this is the first token added, then we don't want to assume any
                         //join logic. We need to figure that out on the second term.
                         $search_text = $word;
                     }
                     break;
             }
         }
         //not 100% sure about this, but it matches the results in search.php
         $search_text = str_replace('"', '\\"', trim($search_text));
     } else {
         $search_text = $criteria->get_raw_keywords();
         //if we are using the raw search text, use the whole string as the display text
         $criteria->set_keyword_display_string('<b><u>' . htmlspecialchars_uni($search_text) . '</u></b>');
         $criteria->set_highlights(array($search_text));
     }
     return $search_text;
 }
Exemple #3
0
 protected function process_sort(vB_Search_Criteria &$criteria)
 {
     $sort_array = $criteria->get_sort();
     $this->sort = array();
     $sort_map = array('user' => 'authorname', 'author' => 'authorname', 'publishdate' => 'publishdate', 'created' => 'created', 'started' => 'created', 'last_post' => 'lastcontent', 'lastcontent' => 'lastcontent', 'textcount' => 'textcount', 'replies' => 'textcount', 'displayorder' => 'displayorder', 'rank' => 'rank', 'relevance' => 'rank', 'votes' => 'votes');
     foreach ($sort_array as $sort => $direction) {
         $direction = strtoupper($direction);
         if (!in_array($direction, array('ASC', 'DESC'))) {
             $direction = 'ASC';
         }
         // if we don't have a sort, or we have an unrecognized sort type default to relevance descending
         if (!$sort or !isset($sort_map[$sort])) {
             $sort = 'relevance';
             $direction = 'DESC';
         }
         //look for a core sort option
         if (isset($sort_map[$sort])) {
             $sort_field = $sort_map[$sort];
             // process rank sortings
             if ($sort_field == 'rank') {
                 $this->what[] = "weight() as rank";
             } else {
                 $sort_field = "{$sort_field}";
             }
             $this->sort[] = $sort_field . ' ' . $direction;
         }
     }
 }
Exemple #4
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;
 }
 /**
  * Hack to get original (unparced) text from search request.
  * Because vBulletin transform it in very stupid way.
  * Then fill some dependent variables.
  *
  * The word build up is taken from the socialgroup/blog implementation
  * The natural language hack is from search.php
  *
  * @param vB_Legacy_Current_User $user user requesting the search
  * @param vB_Search_Criteria $criteria search criteria to process
  */
 protected function _get_search_text($user, $criteria)
 {
     $search_text = $criteria->get_raw_keywords();
     //if we are using the raw search text, use the whole string as the display text
     $criteria->set_keyword_display_string('<b><u>' . htmlspecialchars_uni($search_text) . '</u></b>');
     $criteria->set_highlights(array($search_text));
     return trim($search_text);
 }
Exemple #6
0
 /**
  * Generate a cache key for the first pass of getSearchResults. Build key based on:
  * usergroupids, infractiongroupids, search json, search sort order, search sort by,
  * moderated channels
  *
  * @param vB_Search_Criteria
  *
  * @staticvar array	$hashResult	Array to build hash from
  * @return string
  */
 public static function getTwoPassCacheKey(vB_Search_Criteria $criteria)
 {
     $cacheTTL = vB_Api_Search::getCacheTTL();
     if ($cacheTTL < 1) {
         return false;
     }
     $channelAccess = vB::getUserContext()->getAllChannelAccess();
     $currentUserId = vB::getCurrentSession()->get('userid');
     // Don't use cache if we have a GIT record
     if (!empty($channelAccess['member'])) {
         return false;
     }
     // Not 100% set on this but it seems adding further nodes to the result set
     // could introduce nodes that were grabbed based on nodes that might
     // end up removed on the second pass
     if ($criteria->get_post_processors()) {
         return false;
     }
     $json = $criteria->getJSON();
     //$json['disable_two_pass'] = true;
     if (!empty($json['disable_two_pass']) or !empty($json['my_following']) and !empty($currentUserId) or !empty($json[vB_Api_Search::FILTER_FOLLOW]) or !empty($json['private_messages_only']) or !empty($json['include_private_messages']) or !empty($json['date']) and $json['date'] == vB_Api_Search::FILTER_LASTVISIT or !empty($json['unread_only']) or !empty($json['author']) and !empty($json['exactname']) and ($json['author'] == 'myFriends' or $json['author'] == 'iFollow')) {
         return false;
     }
     // Don't cache for globally ignored users
     if (!empty($currentUserId)) {
         $globalignore = trim(vB::getDatastore()->getOption('globalignore'));
         if (!empty($globalignore)) {
             $blocked = preg_split('#\\s+#s', $globalignore, -1, PREG_SPLIT_NO_EMPTY);
             $bbuserkey = array_search($currentUserId, $blocked);
             if ($bbuserkey !== FALSE and $bbuserkey !== NULL) {
                 return false;
             }
         }
     }
     if (isset($json['ignored_words'])) {
         unset($json['ignored_words']);
     }
     if (isset($json['original_keywords'])) {
         unset($json['original_keywords']);
     }
     // Make sure ugids and ifids are in a consistent order
     $ugids = $ifids = $mod = '';
     $userinfo = vB_User::fetchUserinfo();
     if (!empty($userinfo['membergroupids']) and trim($userinfo['membergroupids']) != '' and $ugids = explode(',', str_replace(' ', '', $userinfo['membergroupids']))) {
         $ugids[] = $userinfo['usergroupid'];
         sort($ugids, SORT_NUMERIC);
         $ugids = array_unique($ugids, SORT_NUMERIC);
         $ugids = implode(',', $ugids);
     } else {
         $ugids = $userinfo['usergroupid'];
     }
     $ifid = !empty($userinfo['infractiongroupid']) ? intval($userinfo['infractiongroupid']) : 0;
     if (!empty($userinfo['infractiongroupids']) and trim($userinfo['infractiongroupids']) != '' and $ifids = explode(',', str_replace(' ', '', $userinfo['infractiongroupids']))) {
         if ($ifid) {
             $ifids[] = $ifid;
         }
         sort($ifids, SORT_NUMERIC);
         $ifids = array_unique($ifids, SORT_NUMERIC);
         $ifids = implode(',', $ifids);
     } else {
         if ($ifid) {
             $ifids = $ifid;
         }
     }
     if (!empty($channelAccess['canmoderate'])) {
         $mod = $channelAccess['canmoderate'];
         sort($mod, SORT_NUMERIC);
         $mod = array_unique($mod, SORT_NUMERIC);
         $mod = implode(',', $mod);
     }
     $hashResult = array('json' => $json, 'so' => $criteria->get_sort_field(), 'sb' => $criteria->get_sort_direction(), 'ul' => vB::getUserContext()->getUserLevel(), 'ug' => $ugids);
     if (!empty($ifids)) {
         $hashResult['if'] = $ifids;
     }
     if (!empty($mod)) {
         $hashResult['mod'] = $mod;
     }
     return 'getSearchResults_' . md5(serialize($hashResult));
 }