Esempio n. 1
0
 /**
  * Perform a search.
  * Returns an array of a total count (total number of matches)
  * and an array of IDs ( 0 => 1203, 1 => 928, 2 => 2938 ).. matching the required number based on pagination. The ids returned would be based on the filters and type of search
  *
  * So if we had 1000 replies, and we are on page 2 of 25 per page, we'd return 25 items offset by 25
  *
  * @return array
  */
 public function search()
 {
     $start = intval(IPSSearchRegistry::get('in.start'));
     $perPage = IPSSearchRegistry::get('opt.search_per_page');
     $sort_by = IPSSearchRegistry::get('in.search_sort_by');
     $sort_order = IPSSearchRegistry::get('in.search_sort_order');
     $search_term = IPSSearchRegistry::get('in.clean_search_term');
     $search_type = IPSSearchRegistry::get('opt.searchType');
     $search_tags = IPSSearchRegistry::get('in.raw_search_tags');
     $search_ids = array();
     $groupby = false;
     $cType = IPSSearchRegistry::get('contextual.type');
     $cId = IPSSearchRegistry::get('contextual.id');
     /* Contextual search */
     if ($cType == 'topic') {
         $search_type = 'content';
         IPSSearchRegistry::set('opt.searchType', 'content');
         IPSSearchRegistry::set('opt.noPostPreview', false);
     }
     /* If searching tags, we don't show a preview */
     if ($search_tags) {
         IPSSearchRegistry::set('opt.noPostPreview', true);
         IPSSearchRegistry::set('opt.searchType', 'titles');
         $search_type = 'titles';
     }
     /* Permissions */
     $permissions = array();
     $permissions['TopicSoftDeleteSee'] = $this->registry->getClass('class_forums')->canSeeSoftDeletedTopics(0);
     $permissions['canQueue'] = $this->registry->getClass('class_forums')->canQueuePosts(0);
     $permissions['PostSoftDeleteSee'] = $this->registry->getClass('class_forums')->canSeeSoftDeletedPosts(0);
     $permissions['SoftDeleteReason'] = $this->registry->getClass('class_forums')->canSeeSoftDeleteReason(0);
     $permissions['SoftDeleteContent'] = $this->registry->getClass('class_forums')->canSeeSoftDeleteContent(0);
     /* Sorting */
     switch ($sort_by) {
         default:
         case 'date':
             $sortKey = 'last_post';
             $sortKeyPost = 'post_date';
             break;
         case 'title':
             $sortKeyPost = $sortKey = 'tordinal';
             break;
         case 'posts':
             $sortKeyPost = $sortKey = 'posts';
             break;
         case 'views':
             $sortKeyPost = $sortKey = 'views';
             break;
     }
     /* Limit Results */
     $this->sphinxClient->SetLimits(intval($start), $perPage);
     /* Loop through the forums and build a list of forums we're allowed access to */
     if (is_array($this->searchForumIds) and count($this->searchForumIds)) {
         $forumIdsOk = $this->searchForumIds;
     } else {
         $forumIdsOk = array();
         $forumIdsBad = array();
         if (!empty(ipsRegistry::$request['search_app_filters']['forums']['forums']) and count(ipsRegistry::$request['search_app_filters']['forums']['forums'])) {
             foreach (ipsRegistry::$request['search_app_filters']['forums']['forums'] as $forum_id) {
                 if ($forum_id) {
                     $data = $this->registry->class_forums->forum_by_id[$forum_id];
                     /* Check for sub forums */
                     $children = ipsRegistry::getClass('class_forums')->forumsGetChildren($forum_id);
                     foreach ($children as $kid) {
                         if (!in_array($kid, ipsRegistry::$request['search_app_filters']['forums']['forums'])) {
                             if (!$this->registry->permissions->check('read', $this->registry->class_forums->forum_by_id[$kid])) {
                                 $forumIdsBad[] = $kid;
                                 continue;
                             }
                             /* Can read, but is it password protected, etc? */
                             if (!$this->registry->class_forums->forumsCheckAccess($kid, 0, 'forum', array(), true)) {
                                 $forumIdsBad[] = $kid;
                                 continue;
                             }
                             if (!$this->registry->class_forums->forum_by_id[$kid]['sub_can_post'] or !$this->registry->class_forums->forum_by_id[$kid]['can_view_others']) {
                                 $forumIdsBad[] = $kid;
                                 continue;
                             }
                             $forumIdsOk[] = $kid;
                         }
                     }
                     /* Can we read? */
                     if (!$this->registry->permissions->check('view', $data)) {
                         $forumIdsBad[] = $forum_id;
                         continue;
                     }
                     /* Can read, but is it password protected, etc? */
                     if (!$this->registry->class_forums->forumsCheckAccess($forum_id, 0, 'forum', array(), true)) {
                         $forumIdsBad[] = $forum_id;
                         continue;
                     }
                     if (!$data['sub_can_post'] or !$data['can_view_others'] and !$this->memberData['g_access_cp']) {
                         $forumIdsBad[] = $forum_id;
                         continue;
                     }
                     $forumIdsOk[] = $forum_id;
                 }
             }
         }
     }
     if (!count($forumIdsOk)) {
         /* Get list of good forum IDs */
         $forumIdsOk = $this->registry->class_forums->fetchSearchableForumIds();
     }
     /* Add allowed forums */
     $forumIdsOk = count($forumIdsOk) ? $forumIdsOk : array(0 => 0);
     /* Contextual */
     if ($cType == 'forum' and $cId and in_array($cId, $forumIdsOk)) {
         $this->sphinxClient->SetFilter('forum_id', array($cId));
     } else {
         $this->sphinxClient->SetFilter('forum_id', $forumIdsOk);
     }
     /* Topic contextual */
     if ($cType == 'topic' and $cId) {
         $this->sphinxClient->SetFilter('tid', array($cId));
     }
     /* Just show topics started by a member if we're search titles + member (#35289) */
     if ($search_type == 'titles' && IPSSearchRegistry::get('in.search_author_id')) {
         $this->sphinxClient->SetFilter('starter_id', array(IPSSearchRegistry::get('in.search_author_id')));
     }
     /* Exclude some items */
     if ($search_type != 'titles') {
         if ($permissions['SoftDeleteContent'] and $permissions['PostSoftDeleteSee'] and $permissions['canQueue']) {
             $this->sphinxClient->SetFilter('queued', array(0, 1, 2));
         } else {
             if ($permissions['SoftDeleteContent'] and $permissions['PostSoftDeleteSee']) {
                 $this->sphinxClient->SetFilter('queued', array(0, 2));
             } else {
                 if ($permissions['canQueue']) {
                     $this->sphinxClient->SetFilter('queued', array(0, 1));
                 } else {
                     $this->sphinxClient->SetFilter('queued', array(0));
                 }
             }
         }
     }
     if ($permissions['SoftDeleteContent'] and $permissions['TopicSoftDeleteSee'] and $permissions['canQueue']) {
         $this->sphinxClient->SetFilter('approved', array(0, 1));
         $this->sphinxClient->SetFilter('soft_deleted', array(0, 1));
     } else {
         if ($permissions['SoftDeleteContent'] and $permissions['TopicSoftDeleteSee']) {
             $this->sphinxClient->SetFilter('approved', array(1));
             $this->sphinxClient->SetFilter('soft_deleted', array(0, 1));
         } else {
             if ($permissions['canQueue']) {
                 $this->sphinxClient->SetFilter('soft_deleted', array(0));
                 $this->sphinxClient->SetFilter('approved', array(0, 1));
             } else {
                 $this->sphinxClient->SetFilter('soft_deleted', array(0));
                 $this->sphinxClient->SetFilter('approved', array(1));
             }
         }
     }
     /* Archive search? */
     if ($this->searchArchives) {
         $this->sphinxClient->SetFilter('archive_status', array(1));
     } else {
         $this->sphinxClient->SetFilter('archive_status', array(0));
     }
     /* Additional filters */
     if (IPSSearchRegistry::get('opt.pCount')) {
         $this->sphinxClient->SetFilterRange('posts', intval(IPSSearchRegistry::get('opt.pCount')), 1500000000);
     }
     if (IPSSearchRegistry::get('opt.pViews')) {
         $this->sphinxClient->SetFilterRange('views', intval(IPSSearchRegistry::get('opt.pViews')), 1500000000);
     }
     /* Date limit */
     if ($this->search_begin_timestamp) {
         if (!$this->search_end_timestamp) {
             $this->search_end_timestamp = time() + 100;
         }
         if ($search_type == 'titles') {
             $this->sphinxClient->SetFilterRange('start_date', $this->search_begin_timestamp, $this->search_end_timestamp);
         } else {
             $this->sphinxClient->SetFilterRange('post_date', $this->search_begin_timestamp, $this->search_end_timestamp);
         }
     }
     if (IPSSearchRegistry::get('opt.noPostPreview') or $search_type == 'titles') {
         $groupby = true;
     }
     /* Check tags */
     $tagIds = array();
     if ($search_tags && $this->settings['tags_enabled']) {
         $tags = $this->registry->tags->search($search_tags, array('meta_parent_id' => $this->request['search_app_filters']['forums']['forums'], 'meta_app' => 'forums', 'meta_area' => 'topics', 'isViewable' => true, 'sortOrder' => $sort_order));
         foreach ($tags as $id => $data) {
             $tagIds[] = $data['tag_id'];
         }
         if ($search_term) {
             if (count($tagIds)) {
                 $this->sphinxClient->SetFilter('tag_id', $tagIds);
             }
         } else {
             if (!$tagIds) {
                 return array('count' => 0, 'resultSet' => array());
             } else {
                 /* We have tags but no search term, so just return the tids now */
                 IPSSearchRegistry::set('set.returnType', 'tids');
                 $tids = array();
                 $this->DB->build(array('select' => 'c.tag_meta_id', 'from' => array('core_tags' => 'c'), 'where' => 'c.tag_id IN (' . implode(',', $tagIds) . ')', 'order' => 'c.tag_added DESC', 'limit' => array(0, 1000), 'add_join' => array(array("select" => 't.title, t.posts, t.views, t.last_post', "from" => array('topics' => 't'), "where" => "c.tag_meta_id=t.tid", 'type' => 'left'))));
                 $this->DB->execute();
                 $rows = array();
                 while ($row = $this->DB->fetch()) {
                     $rows[] = $row;
                 }
                 /* Sorting */
                 switch ($sort_by) {
                     default:
                     case 'date':
                         $sortKey = !IPSSearchRegistry::searchTitleOnly() ? $this->table['post_date'] : 'last_post';
                         $sortType = 'numerical';
                         break;
                     case 'title':
                         $sortKey = 'title';
                         $sortType = 'string';
                         break;
                     case 'posts':
                         $sortKey = 'posts';
                         $sortType = 'numerical';
                         break;
                     case 'views':
                         $sortKey = 'views';
                         $sortType = 'numerical';
                         break;
                 }
                 IPSSearch::$ask = 'last_post';
                 IPSSearch::$aso = strtolower($sort_order);
                 IPSSearch::$ast = 'numerical';
                 usort($rows, array("IPSSearch", "usort"));
                 $c = 0;
                 $got = 0;
                 foreach ($rows as $row) {
                     $c++;
                     if (IPSSearchRegistry::get('in.start') and IPSSearchRegistry::get('in.start') >= $c) {
                         continue;
                     }
                     $tids[] = $row['tag_meta_id'];
                     $got++;
                     /* Done? */
                     if (IPSSearchRegistry::get('opt.search_per_page') and $got >= IPSSearchRegistry::get('opt.search_per_page')) {
                         break;
                     }
                 }
                 return array('count' => count($rows), 'resultSet' => $tids);
             }
         }
     }
     /* Set sort order */
     if ($sort_order == 'asc') {
         $this->sphinxClient->SetSortMode(SPH_SORT_ATTR_ASC, $sortKey);
     } else {
         $this->sphinxClient->SetSortMode(SPH_SORT_ATTR_DESC, $sortKey);
     }
     /* Generate sphinx search query */
     switch ($search_type) {
         case 'titles':
             /* Group by */
             if ($groupby) {
                 /* @link http://community.invisionpower.com/topic/335036-sphinx-vncactive-content-sorting/ 
                    @link http://community.invisionpower.com/tracker/issue-34481-sphinx-sorting-broken/*/
                 $this->sphinxClient->SetGroupDistinct("tid");
                 $this->sphinxClient->SetGroupBy('tid', SPH_GROUPBY_ATTR, $sortKey . ' ' . $sort_order);
             }
             $_s = $search_term ? '@title ' . $search_term : '';
             break;
         case 'content':
             /* Group by */
             if ($groupby) {
                 $this->sphinxClient->SetSortMode(SPH_SORT_EXTENDED, $sortKeyPost . ' DESC');
                 $this->sphinxClient->SetGroupBy('tid', SPH_GROUPBY_ATTR, $sortKey . ' ' . $sort_order);
                 IPSSearchRegistry::set('set.searchResultType', 'both');
             }
             $_s = $search_term ? '@' . $this->table['post'] . ' ' . $search_term : '';
             break;
         case 'both':
         default:
             /* Group by */
             if ($groupby) {
                 $this->sphinxClient->SetSortMode(SPH_SORT_EXTENDED, $sortKeyPost . ' DESC');
                 $this->sphinxClient->SetGroupBy('tid', SPH_GROUPBY_ATTR, $sortKey . ' ' . $sort_order);
             }
             IPSSearchRegistry::set('set.searchResultType', 'both');
             $_s = ($search_term and strstr($search_term, '"')) ? '@' . $this->table['post'] . ' ' . $search_term . ' | @title ' . $search_term : ($search_term ? '@(' . $this->table['post'] . ',title) ' . $search_term : '');
             break;
     }
     /* Perform search */
     $result = $this->sphinxClient->Query($_s, $this->settings['sphinx_prefix'] . $this->table['forums_search_posts_main'] . ', ' . $this->settings['sphinx_prefix'] . $this->table['forums_search_posts_delta']);
     /* Log errors */
     $this->logSphinxWarnings();
     /* Get result ids */
     if (is_array($result['matches']) && count($result['matches'])) {
         $c = 0;
         foreach ($result['matches'] as $res) {
             $search_ids[] = $search_type == 'titles' && IPSSearchRegistry::get('set.searchResultType') != 'both' ? $res['attrs']['tid'] : $res['attrs']['search_id'];
         }
     }
     /* Set return type */
     if ($search_type == 'titles' && IPSSearchRegistry::get('set.searchResultType') != 'both') {
         IPSSearchRegistry::set('set.returnType', 'tids');
     } else {
         IPSSearchRegistry::set('set.returnType', 'pids');
     }
     /* Return it */
     return array('count' => intval($result['total_found']) > 1000 ? 1000 : $result['total_found'], 'resultSet' => $search_ids);
 }
Esempio n. 2
0
 /**
  * Formats / grabs extra data for results
  * Takes an array of IDS (can be IDs from anything) and returns an array of expanded data.
  *
  * @param	array 	$ids			Ids
  * @return array
  */
 public function processResultsComments($ids)
 {
     /* INIT */
     $sort_order = IPSSearchRegistry::get('in.search_sort_order');
     $search_term = IPSSearchRegistry::get('in.clean_search_term');
     $content_title_only = IPSSearchRegistry::get('opt.searchType') == 'content' ? false : true;
     $members = array();
     $results = array();
     $statusIds = array();
     $replyIds = IPSSearchRegistry::get('_internal.replyIds');
     $replyData = IPSSearchRegistry::get('_internal.replyData');
     $replies = array();
     $sortKey = '';
     /* Got some? */
     if (count($ids)) {
         /* Set vars */
         IPSSearch::$ask = 'status_date';
         IPSSearch::$aso = strtolower($sort_order);
         IPSSearch::$ast = 'numerical';
         /* Get the status updates */
         $this->DB->build(array('select' => "s.*", 'from' => array('member_status_updates' => 's'), 'where' => 's.status_id IN( ' . implode(',', $ids) . ')', 'add_join' => array_merge(array(array('select' => 'm.member_id as owner_id, m.members_display_name as owner_display_name, m.members_seo_name as owner_seo_name', 'from' => array('members' => 'm'), 'where' => 'm.member_id=s.status_member_id', 'type' => 'left'), array('select' => 'mem.member_id as author_id, mem.members_display_name as author_display_name, mem.members_seo_name as author_seo_name', 'from' => array('members' => 'mem'), 'where' => 'mem.member_id=s.status_author_id', 'type' => 'left')))));
         /* Grab data */
         $this->DB->execute();
         /* Grab the results */
         while ($row = $this->DB->fetch()) {
             $statusIds[$row['status_id']] = $row;
         }
         /* Sort */
         if (count($statusIds)) {
             usort($statusIds, array("IPSSearch", "usort"));
             foreach ($statusIds as $id => $row) {
                 /* Do we have any reply data? */
                 if (!empty($replyData[$id])) {
                     $row = array_merge($row, $replyData[$id]);
                 }
                 /* Get author data? */
                 if (!empty($row['status_author_id'])) {
                     $members[$row['status_author_id']] = $row['status_author_id'];
                 }
                 if (!empty($row['status_member_id'])) {
                     $members[$row['status_member_id']] = $row['status_member_id'];
                 }
                 if (!empty($row['reply_member_id'])) {
                     $members[$row['reply_member_id']] = $row['reply_member_id'];
                 }
                 $results[$row['status_id']] = $row;
             }
         }
         /* Need to load members? */
         if (count($members)) {
             $mems = IPSMember::load($members, 'all');
             foreach ($results as $id => $r) {
                 $_status_member = IPSMember::buildDisplayData($mems[$r['status_member_id']], array('reputation' => 0, 'warn' => 0));
                 $_status_author = IPSMember::buildDisplayData($mems[$r['status_author_id']], array('reputation' => 0, 'warn' => 0));
                 $results[$id]['status_member'] = $_status_member;
                 $results[$id]['status_author'] = $_status_author;
                 if (!empty($r['reply_member_id'])) {
                     $results[$id]['reply_author'] = IPSMember::buildDisplayData($mems[$r['reply_member_id']], array('reputation' => 0, 'warn' => 0));
                 }
             }
         }
     }
     return $results;
 }
Esempio n. 3
0
 /**
  * Formats / grabs extra data for results
  * Takes an array of IDS (can be IDs from anything) and returns an array of expanded data.
  *
  * @param	array 	$ids			Ids
  * @param	array	$followData		Retrieve the follow meta data
  * @return array
  */
 public function processResults($ids, $followData = array())
 {
     /* INIT */
     $sort_by = IPSSearchRegistry::get('in.search_sort_by');
     $sort_order = IPSSearchRegistry::get('in.search_sort_order');
     $search_term = IPSSearchRegistry::get('in.clean_search_term');
     $content_title_only = IPSSearchRegistry::searchTitleOnly();
     $_post_joins = array();
     $members = array();
     $results = array();
     $topicIds = array();
     $dots = array();
     $sortKey = '';
     $sortType = '';
     $_sdTids = array();
     $_sdPids = array();
     /* Set up some basic permissions */
     $permissions['PostSoftDeleteSee'] = $this->registry->getClass('class_forums')->canSeeSoftDeletedPosts(0);
     $permissions['TopicSoftDeleteSee'] = $this->registry->getClass('class_forums')->canSeeSoftDeletedTopics(0);
     $permissions['canQueue'] = $this->registry->getClass('class_forums')->canQueuePosts(0);
     $permissions['SoftDeleteReason'] = $this->registry->getClass('class_forums')->canSeeSoftDeleteReason(0);
     $permissions['SoftDeleteContent'] = $this->registry->getClass('class_forums')->canSeeSoftDeleteContent(0);
     $permissions['PostSoftDeleteRestore'] = $this->registry->getClass('class_forums')->can_Un_SoftDeletePosts(0);
     $permissions['TopicSoftDeleteRestore'] = $this->registry->getClass('class_forums')->can_Un_SoftDeleteTopics(0);
     /* Got some? */
     if (count($ids)) {
         /* Cache? */
         if (IPSContentCache::isEnabled()) {
             if (IPSContentCache::fetchSettingValue('post')) {
                 $_post_joins[] = IPSContentCache::join('post', 'p.' . $this->table['pid']);
             }
             if (IPSContentCache::fetchSettingValue('sig')) {
                 $_post_joins[] = IPSContentCache::join('sig', 'p.' . $this->table['author_id'], 'ccb', 'left', 'ccb.cache_content as cache_content_sig, ccb.cache_updated as cache_updated_sig');
             }
         }
         if ($this->registry->tags->isEnabled()) {
             $_post_joins[] = $this->registry->tags->getCacheJoin(array('meta_id_field' => 't.tid'));
         }
         /* Sorting */
         switch ($sort_by) {
             default:
             case 'date':
                 $sortKey = IPSSearchRegistry::get('set.returnType') == 'tids' ? 'last_post' : $this->table['post_date'];
                 $sortType = 'numerical';
                 break;
             case 'title':
                 $sortKey = 'title';
                 $sortType = 'string';
                 break;
             case 'posts':
                 $sortKey = 'posts';
                 $sortType = 'numerical';
                 break;
             case 'views':
                 $sortKey = 'views';
                 $sortType = 'numerical';
                 break;
         }
         /* Set vars */
         IPSSearch::$ask = $sortKey;
         IPSSearch::$aso = strtolower($sort_order);
         IPSSearch::$ast = $sortType;
         /* If we are search in titles only, then the ID array will be TIDs */
         if (IPSSearchRegistry::get('set.returnType') == 'tids') {
             $k = 'tid';
             $this->DB->build(array('select' => "t.*", 'from' => array('topics' => 't'), 'where' => 't.tid IN( ' . implode(',', $ids) . ')', 'add_join' => array_merge(array(array('select' => 'p.*', 'from' => array($this->table['_table_'] => 'p'), 'where' => 'p.' . $this->table['pid'] . '=t.topic_firstpost', 'type' => 'left'), array('select' => 'm.member_id, m.members_display_name, m.members_seo_name', 'from' => array('members' => 'm'), 'where' => 'm.member_id=p.' . $this->table['author_id'], 'type' => 'left')), $_post_joins)));
         } else {
             $k = $this->table['pid'];
             $this->DB->build(array('select' => "p.*", 'from' => array($this->table['_table_'] => 'p'), 'where' => 'p.' . $this->table['pid'] . ' IN( ' . implode(',', $ids) . ')', 'add_join' => array_merge(array(array('select' => 't.*', 'from' => array('topics' => 't'), 'where' => 't.tid=p.' . $this->table['topic_id'], 'type' => 'left'), array('select' => 'm.member_id, m.members_display_name, m.members_seo_name', 'from' => array('members' => 'm'), 'where' => 'm.member_id=p.' . $this->table['author_id'], 'type' => 'left')), $_post_joins)));
         }
         /* Grab data */
         $this->DB->execute();
         /* Grab the results */
         while ($row = $this->DB->fetch()) {
             $_rows[$row[$k]] = $this->searchArchives ? $this->archiveReader->archiveToNativeFields($row) : $row;
         }
         /* Get the 'follow' meta data? */
         if (count($followData)) {
             $followData = classes_like_meta::get($followData);
             /* Merge the data from the follow class into the results */
             foreach ($followData as $_formatted) {
                 $_rows[$_formatted['like_rel_id']]['_followData'] = $_formatted;
             }
         }
         /* Sort */
         if (count($_rows)) {
             usort($_rows, array("IPSSearch", "usort"));
             foreach ($_rows as $id => $row) {
                 /* Prevent member from stepping on it */
                 $row['topic_title'] = $row['title'];
                 /* Get author data? */
                 if ($k == 'tid') {
                     if (!empty($row['last_poster_id'])) {
                         $members[$row['last_poster_id']] = $row['last_poster_id'];
                     }
                 } else {
                     if (!empty($row['author_id'])) {
                         $members[$row['author_id']] = $row['author_id'];
                     }
                 }
                 /* Topic ids? */
                 if (!empty($row['topic_id'])) {
                     $topicIds[$row['topic_id']] = $row['topic_id'];
                 }
                 /* If we're using sphinx, check forum permissions again as the 15 minute delta rebuild could expose a moved topic before deltas rebuild.
                    We don't need to do this for SQL search as the results are delivered live and lets face it, we can do without the load  */
                 if ($this->settings['search_method'] != 'traditional') {
                     /* Can we read? */
                     if (!$this->registry->permissions->check('view', $this->registry->class_forums->forum_by_id[$row['forum_id']])) {
                         continue;
                     }
                     /* Can read, but is it password protected, etc? */
                     if (!$this->registry->class_forums->forumsCheckAccess($row['forum_id'], 0, 'forum', array(), true)) {
                         continue;
                     }
                 }
                 $row['cleanSearchTerm'] = urlencode($search_term);
                 $row['topicPrefix'] = $row['pinned'] ? $this->registry->getClass('output')->getTemplate('forum')->topicPrefixWrap($this->lang->words['pre_pinned']) : '';
                 $row['_isVisible'] = $this->registry->getClass('class_forums')->fetchHiddenTopicType($row) == 'visible' ? true : false;
                 $row['_isHidden'] = $this->registry->getClass('class_forums')->fetchHiddenTopicType($row) == 'hidden' ? true : false;
                 $row['_isDeleted'] = $this->registry->getClass('class_forums')->fetchHiddenTopicType($row) == 'sdelete' ? true : false;
                 $row['_p_isVisible'] = $this->registry->getClass('class_forums')->fetchHiddenType($row) == 'visible' ? true : false;
                 $row['_p_isHidden'] = $this->registry->getClass('class_forums')->fetchHiddenType($row) == 'hidden' ? true : false;
                 $row['_p_isDeleted'] = $this->registry->getClass('class_forums')->fetchHiddenType($row) == 'sdelete' ? true : false;
                 /* Hidden and we do not have permission? */
                 if ($row['_isHidden'] and !$permissions['canQueue']) {
                     continue;
                 }
                 /* Is the topic deleted? If so, then the first post will appear as such */
                 if ($row['_isDeleted'] and $permissions['TopicSoftDeleteSee']) {
                     $row['_p_isDeleted'] = true;
                     $_sdPids[$row['pid']] = $row['pid'];
                 }
                 /* Collect TIDS of soft deleted topics */
                 if ($row['_isDeleted']) {
                     if ($permissions['TopicSoftDeleteSee']) {
                         $_sdTids[$row['tid']] = $row['tid'];
                     } else {
                         continue;
                     }
                 }
                 /* Collect TIDS of soft deleted topics */
                 if ($row['_p_isDeleted']) {
                     if ($permissions['PostSoftDeleteSee']) {
                         $_sdPids[$row['pid']] = $row['pid'];
                     } else {
                         continue;
                     }
                 }
                 /* Tags */
                 if (!empty($row['tag_cache_key'])) {
                     $row['tags'] = $this->registry->tags->formatCacheJoinData($row);
                 }
                 $results[$k == 'tid' ? $row['tid'] : $row['pid']] = $this->genericizeResults($row);
             }
         }
         /* Need to load members? */
         if (count($members)) {
             $mems = IPSMember::load($members, 'all');
             $mems[0] = array();
             foreach ($results as $id => $r) {
                 $_memberIdColumn = IPSSearchRegistry::get('set.returnType') == 'tids' ? 'last_poster_id' : 'author_id';
                 if (isset($mems[$r[$_memberIdColumn]])) {
                     $mems[$r[$_memberIdColumn]]['m_posts'] = $mems[$r[$_memberIdColumn]]['posts'];
                     unset($mems[$r[$_memberIdColumn]]['last_post']);
                     if (isset($r['cache_content_sig'])) {
                         $mems[$r[$_memberIdColumn]]['cache_content'] = $r['cache_content_sig'];
                         $mems[$r[$_memberIdColumn]]['cache_updated'] = $r['cache_updated_sig'];
                     }
                     $_mem = IPSMember::buildDisplayData($mems[$r[$_memberIdColumn]], array('reputation' => 0, 'warn' => 0));
                     unset($_mem['cache_content'], $_mem['cache_updated']);
                     $results[$id]['_realPosts'] = $results[$id]['posts'];
                     $results[$id] = array_merge($results[$id], $_mem);
                     $results[$id]['posts'] = $results[$id]['_realPosts'];
                 }
             }
         }
         /* Generate 'dot' folder icon */
         if ($this->settings['show_user_posted'] and count($topicIds)) {
             $_queued = $this->registry->class_forums->fetchPostHiddenQuery(array('visible'), '');
             $this->DB->build(array('select' => 'author_id, topic_id', 'from' => 'posts', 'where' => $_queued . ' AND author_id=' . $this->memberData['member_id'] . ' AND topic_id IN(' . implode(',', $topicIds) . ')'));
             $this->DB->execute();
             while ($p = $this->DB->fetch()) {
                 $dots[$p['topic_id']] = 1;
             }
             /* Merge into results */
             foreach ($results as $id => $r) {
                 if (isset($dots[$r['topic_id']])) {
                     $results[$id]['_hasPosted'] = 1;
                 }
             }
         }
         /* Got any deleted items */
         if (count($_sdTids)) {
             $sData = IPSDeleteLog::fetchEntries($_sdTids, 'topic', false);
             if (count($sData)) {
                 foreach ($results as $id => $data) {
                     if (isset($_sdTids[$data['tid']])) {
                         $results[$id]['sData'] = $sData[$data['tid']];
                         $results[$id]['permissions'] = $permissions;
                     }
                 }
             }
         }
         /* Got any deleted items */
         if (count($_sdPids)) {
             $sData = IPSDeleteLog::fetchEntries($_sdPids, 'post', false);
             if (count($sData)) {
                 foreach ($results as $id => $data) {
                     if (isset($_sdPids[$data['pid']]) and !isset($results[$id]['sData'])) {
                         $results[$id]['sData'] = $sData[$data['pid']];
                         $results[$id]['permissions'] = $permissions;
                     }
                 }
             }
         }
     }
     return $results;
 }
Esempio n. 4
0
 /**
  * Builds the where portion of a search string
  *
  * @param	string	$search_term		The string to use in the search
  * @param	bool	$content_title_only	Search only title records
  * @param	string	$order				Order by data
  * @param	bool	$onlyPosts			Enforce posts only
  * @param	bool	$noForums			Don't check forums that posts are in
  * @return	string
  */
 protected function _buildWhereStatement($search_term, $content_title_only = false, $order = '', $onlyPosts = null, $noForums = false)
 {
     /* INI */
     $where_clause = array();
     $onlyPosts = $onlyPosts !== null ? $onlyPosts : IPSSearchRegistry::get('opt.searchType') == 'content';
     $sort_by = IPSSearchRegistry::get('in.search_sort_by');
     $sort_order = IPSSearchRegistry::get('in.search_sort_order');
     $sortKey = '';
     $sortType = '';
     $cType = IPSSearchRegistry::get('contextual.type');
     $cId = IPSSearchRegistry::get('contextual.id');
     $search_tags = IPSSearchRegistry::get('in.raw_search_tags');
     /* Loop through the forums and build a list of forums we're allowed access to */
     $forumIdsOk = array();
     $forumIdsBad = array();
     if (!empty(ipsRegistry::$request['search_app_filters']['forums']['forums']) and count(ipsRegistry::$request['search_app_filters']['forums']['forums'])) {
         foreach (ipsRegistry::$request['search_app_filters']['forums']['forums'] as $forum_id) {
             if ($forum_id) {
                 $data = $this->registry->class_forums->forum_by_id[$forum_id];
                 /* Check for sub forums */
                 $children = ipsRegistry::getClass('class_forums')->forumsGetChildren($forum_id);
                 foreach ($children as $kid) {
                     if (!in_array($kid, ipsRegistry::$request['search_app_filters']['forums']['forums'])) {
                         if (!$this->registry->permissions->check('read', $this->registry->class_forums->forum_by_id[$kid])) {
                             $forumIdsBad[] = $kid;
                             continue;
                         }
                         /* Can read, but is it password protected, etc? */
                         if (!$this->registry->class_forums->forumsCheckAccess($kid, 0, 'forum', array(), true)) {
                             $forumIdsBad[] = $kid;
                             continue;
                         }
                         if (!$this->registry->class_forums->forum_by_id[$kid]['sub_can_post'] or !$this->registry->class_forums->forum_by_id[$kid]['can_view_others']) {
                             $forumIdsBad[] = $kid;
                             continue;
                         }
                         $forumIdsOk[] = $kid;
                     }
                 }
                 /* Can we read? */
                 if (!$this->registry->permissions->check('view', $data)) {
                     $forumIdsBad[] = $forum_id;
                     continue;
                 }
                 /* Can read, but is it password protected, etc? */
                 if (!$this->registry->class_forums->forumsCheckAccess($forum_id, 0, 'forum', array(), true)) {
                     $forumIdsBad[] = $forum_id;
                     continue;
                 }
                 if ((!$data['sub_can_post'] or !$data['can_view_others']) and !$this->memberData['g_access_cp']) {
                     $forumIdsBad[] = $forum_id;
                     continue;
                 }
                 $forumIdsOk[] = $forum_id;
             }
         }
     }
     if (!count($forumIdsOk)) {
         /* Get list of good forum IDs */
         $forumIdsOk = $this->registry->class_forums->fetchSearchableForumIds();
     }
     /* Add allowed forums */
     if ($noForums !== true) {
         $forumIdsOk = count($forumIdsOk) ? $forumIdsOk : array(0 => 0);
         /* Contextual */
         if ($cType == 'forum' and $cId and in_array($cId, $forumIdsOk)) {
             $where_clause[] = "t.forum_id=" . $cId;
         } else {
             $where_clause[] = "t.forum_id IN (" . implode(",", $forumIdsOk) . ")";
         }
     }
     /* Topic contextual */
     if ($cType == 'topic' and $cId) {
         $where_clause[] = "t.tid=" . $cId;
     }
     /* Exclude some items */
     $permissions = array();
     $permissions['TopicSoftDeleteSee'] = $this->registry->getClass('class_forums')->canSeeSoftDeletedTopics(0);
     $permissions['canQueue'] = $this->registry->getClass('class_forums')->canQueuePosts(0);
     $permissions['PostSoftDeleteSee'] = $this->registry->getClass('class_forums')->canSeeSoftDeletedPosts(0);
     $permissions['SoftDeleteReason'] = $this->registry->getClass('class_forums')->canSeeSoftDeleteReason(0);
     $permissions['SoftDeleteContent'] = $this->registry->getClass('class_forums')->canSeeSoftDeleteContent(0);
     if (!$content_title_only) {
         if ($permissions['SoftDeleteContent'] and $permissions['PostSoftDeleteSee'] and $permissions['canQueue']) {
             $where_clause[] = $this->registry->class_forums->fetchPostHiddenQuery(array('visible', 'hidden', 'sdeleted'), $this->table['_prefix_']);
         } else {
             if ($permissions['SoftDeleteContent'] and $permissions['PostSoftDeleteSee']) {
                 $where_clause[] = $this->registry->class_forums->fetchPostHiddenQuery(array('visible', 'sdeleted'), $this->table['_prefix_']);
             } else {
                 if ($permissions['canQueue']) {
                     $where_clause[] = $this->registry->class_forums->fetchPostHiddenQuery(array('visible', 'hidden'), $this->table['_prefix_']);
                 } else {
                     $where_clause[] = $this->registry->class_forums->fetchPostHiddenQuery(array('visible'), $this->table['_prefix_']);
                 }
             }
         }
     }
     if ($permissions['SoftDeleteContent'] and $permissions['TopicSoftDeleteSee'] and $permissions['canQueue']) {
         $where_clause[] = $this->registry->class_forums->fetchTopicHiddenQuery(array('visible', 'hidden', 'sdeleted'), 't.');
     } else {
         if ($permissions['SoftDeleteContent'] and $permissions['TopicSoftDeleteSee']) {
             $where_clause[] = $this->registry->class_forums->fetchTopicHiddenQuery(array('visible', 'sdeleted'), 't.');
         } else {
             if ($permissions['canQueue']) {
                 $where_clause[] = $this->registry->class_forums->fetchTopicHiddenQuery(array('visible', 'hidden'), 't.');
             } else {
                 $where_clause[] = $this->registry->class_forums->fetchTopicHiddenQuery(array('visible'), 't.');
             }
         }
     }
     /* Live or archived? */
     if ($this->searchArchives) {
         $where_clause[] = $this->registry->class_forums->fetchTopicArchiveQuery(array('working', 'archived'), 't.');
     } else {
         $where_clause[] = $this->registry->class_forums->fetchTopicArchiveQuery(array('not', 'exclude'), 't.');
     }
     if ($search_term) {
         $search_term = str_replace('"', '"', $search_term);
         if ($content_title_only) {
             $where_clause[] = $this->DB->buildSearchStatement('t.title', $search_term, true, false, ipsRegistry::$settings['use_fulltext']);
             IPSSearchRegistry::set('set.returnType', 'tids');
         } else {
             if ($onlyPosts) {
                 $where_clause[] = $this->DB->buildSearchStatement('p.' . $this->table['post'], $search_term, true, false, ipsRegistry::$settings['use_fulltext']);
                 IPSSearchRegistry::set('set.returnType', 'pids');
             } else {
                 IPSSearchRegistry::set('set.returnType', 'pids');
                 /* Sorting */
                 switch ($sort_by) {
                     default:
                     case 'date':
                         $sortKey = 'last_post';
                         $sortType = 'numerical';
                         break;
                     case 'title':
                         $sortKey = 'title';
                         $sortType = 'string';
                         break;
                     case 'posts':
                         $sortKey = 'posts';
                         $sortType = 'numerical';
                         break;
                     case 'views':
                         $sortKey = 'views';
                         $sortType = 'numerical';
                         break;
                 }
                 /* Set vars */
                 IPSSearch::$ask = $sortKey;
                 IPSSearch::$aso = strtolower($sort_order);
                 IPSSearch::$ast = $sortType;
                 /* Find topic ids that match */
                 $tids = array(0 => 0);
                 $pids = array(0 => 0);
                 $this->DB->build(array('select' => "t.tid, t.last_post, t.forum_id", 'from' => 'topics t', 'where' => str_replace('p.' . $this->table['author_id'], 't.starter_id', $this->_buildWhereStatement($search_term, true, $order, null)), 'order' => 't.' . $sortKey . ' ' . $sort_order, 'limit' => array(0, IPSSearchRegistry::get('set.hardLimit'))));
                 $i = $this->DB->execute();
                 /* Grab the results */
                 while ($row = $this->DB->fetch($i)) {
                     $_rows[$row['tid']] = $row;
                 }
                 /* Sort */
                 if (count($_rows)) {
                     usort($_rows, array("IPSSearch", "usort"));
                     foreach ($_rows as $id => $row) {
                         $tids[] = $row['tid'];
                     }
                 }
                 /* Now get the Pids */
                 if (count($tids) > 1) {
                     $this->DB->build(array('select' => $this->table['pid'], 'from' => $this->table['_table_'], 'where' => $this->table['topic_id'] . ' IN (' . implode(',', $tids) . ') AND ' . $this->table['new_topic'] . '=1'));
                     $i = $this->DB->execute();
                     while ($row = $this->DB->fetch()) {
                         $pids[$row[$this->table['pid']]] = $row[$this->table['pid']];
                     }
                 }
                 /* Set vars */
                 IPSSearch::$ask = $sortKey == 'last_post' ? $this->table['post_date'] : $sortKey;
                 IPSSearch::$aso = strtolower($sort_order);
                 IPSSearch::$ast = $sortType;
                 $this->DB->build(array('select' => "p.{$this->table['pid']}, p.{$this->table['queued']}", 'from' => array($this->table['_table_'] => 'p'), 'where' => $this->_buildWhereStatement($search_term, false, $order, true), 'order' => IPSSearch::$ask . ' ' . IPSSearch::$aso, 'limit' => array(0, IPSSearchRegistry::get('set.hardLimit')), 'add_join' => array(array('select' => 't.approved, t.forum_id', 'from' => array('topics' => 't'), 'where' => 'p.' . $this->table['topic_id'] . '=t.tid', 'type' => 'left'))));
                 $i = $this->DB->execute();
                 /* Grab the results */
                 while ($row = $this->DB->fetch($i)) {
                     $_prows[$row[$this->table['pid']]] = $row;
                 }
                 /* Sort */
                 if (count($_prows)) {
                     usort($_prows, array("IPSSearch", "usort"));
                     foreach ($_prows as $id => $row) {
                         $pids[$row[$this->table['pid']]] = $row[$this->table['pid']];
                     }
                 }
                 $where_clause[] = '( p.' . $this->table['pid'] . ' IN (' . implode(',', $pids) . ') )';
             }
         }
     }
     /* No moved topic links */
     $where_clause[] = "t.state != 'link'";
     /* Date Restrict */
     if ($this->search_begin_timestamp && $this->search_end_timestamp) {
         $where_clause[] = $this->DB->buildBetween($content_title_only ? "t.last_post" : "p." . $this->table['post_date'], $this->search_begin_timestamp, $this->search_end_timestamp);
     } else {
         if ($this->search_begin_timestamp) {
             $where_clause[] = $content_title_only ? "t.last_post > {$this->search_begin_timestamp}" : "p." . $this->table['post_date'] . " > {$this->search_begin_timestamp}";
         }
         if ($this->search_end_timestamp) {
             $where_clause[] = $content_title_only ? "t.last_post < {$this->search_end_timestamp}" : "p." . $this->table['post_date'] . " < {$this->search_end_timestamp}";
         }
     }
     /* Add in AND where conditions */
     if (isset($this->whereConditions['AND']) && count($this->whereConditions['AND'])) {
         $where_clause = array_merge($where_clause, $this->whereConditions['AND']);
     }
     /* ADD in OR where conditions */
     if (isset($this->whereConditions['OR']) && count($this->whereConditions['OR'])) {
         $where_clause[] = '( ' . implode(' OR ', $this->whereConditions['OR']) . ' )';
     }
     /* Build and return the string */
     return implode(" AND ", $where_clause);
 }
Esempio n. 5
0
 /**
  * Builds the where portion of a search string
  *
  * @param	string	$search_term			The string to use in the search
  * @param	bool	$searchType		Search only title records
  * @return	string
  */
 protected function _buildCommentsWhereStatement($search_term, $searchType = null)
 {
     /* INI */
     $where_clause = array();
     $searchType = $searchType === null ? IPSSearchRegistry::get('opt.searchType') : $searchType;
     $sort_order = IPSSearchRegistry::get('in.search_sort_order');
     if ($search_term) {
         if ($searchType == 'titles') {
             $where_clause[] = $this->DB->buildSearchStatement('s.status_content', $search_term, true, false, false);
         } else {
             if ($searchType == 'content') {
                 $where_clause[] = $this->DB->buildSearchStatement('r.reply_content', $search_term, true, false, false);
             } else {
                 /* Set vars */
                 IPSSearch::$ask = 'status_date';
                 IPSSearch::$aso = strtolower($sort_order);
                 IPSSearch::$ast = 'numerical';
                 /* Find topic ids that match */
                 $tids = array();
                 $pids = array();
                 $this->DB->build(array('select' => "s.status_id, s.status_date", 'from' => 'member_status_updates s', 'where' => $this->_buildCommentsWhereStatement($search_term, 'titles'), 'order' => 's.status_date ' . $sort_order, 'limit' => array(0, IPSSearchRegistry::get('set.hardLimit'))));
                 $i = $this->DB->execute();
                 /* Grab the results */
                 while ($row = $this->DB->fetch($i)) {
                     $_rows[$row['status_id']] = $row;
                 }
                 /* Sort */
                 if (count($_rows)) {
                     usort($_rows, array("IPSSearch", "usort"));
                     foreach ($_rows as $id => $row) {
                         $tids[] = $row['status_id'];
                     }
                 }
                 /* Set vars */
                 IPSSearch::$ask = 'reply_date';
                 IPSSearch::$aso = strtolower($sort_order);
                 IPSSearch::$ast = 'numerical';
                 $this->DB->build(array('select' => "r.reply_id, r.reply_date, r.reply_status_id as status_id", 'from' => array('member_status_replies' => 'r'), 'add_join' => array(array('select' => 's.status_id, s.status_member_id, s.status_author_id', 'from' => array('member_status_updates' => 's'), 'where' => 's.status_id=r.reply_status_id', 'type' => 'left')), 'where' => $this->_buildCommentsWhereStatement($search_term, 'content'), 'order' => IPSSearch::$ask . ' ' . IPSSearch::$aso, 'limit' => array(0, IPSSearchRegistry::get('set.hardLimit'))));
                 $i = $this->DB->execute();
                 /* Grab the results */
                 while ($row = $this->DB->fetch($i)) {
                     $tids[] = $row['status_id'];
                     $pids[] = $row['reply_id'];
                 }
                 if (count($pids)) {
                     IPSSearchRegistry::set('_internal.replyIds', $pids);
                 }
                 $where_clause[] = '( s.status_id IN (' . (count($tids) ? implode(',', $tids) : 0) . ') )';
             }
         }
     }
     /* Add in AND where conditions */
     if (isset($this->whereConditions['AND']) && count($this->whereConditions['AND'])) {
         $where_clause = array_merge($where_clause, $this->whereConditions['AND']);
     }
     /* ADD in OR where conditions */
     if (isset($this->whereConditions['OR']) && count($this->whereConditions['OR'])) {
         $where_clause[] = '( ' . implode(' OR ', $this->whereConditions['OR']) . ' )';
     }
     /* Date Restrict */
     if ($this->search_begin_timestamp && $this->search_end_timestamp) {
         $where_clause[] = $this->DB->buildBetween($searchType == 'content' ? "r.reply_date" : "s.status_date", $this->search_begin_timestamp, $this->search_end_timestamp);
     } else {
         if ($this->search_begin_timestamp) {
             $where_clause[] = $searchType == 'content' ? "r.reply_date > {$this->search_begin_timestamp}" : "s.status_date > {$this->search_begin_timestamp}";
         }
         if ($this->search_end_timestamp) {
             $where_clause[] = $searchType == 'content' ? "r.reply_date < {$this->search_end_timestamp}" : "s.status_date < {$this->search_end_timestamp}";
         }
     }
     /* Build and return the string */
     return implode(" AND ", $where_clause);
 }