/** * Perform the search * @param array $tags * @param array $options */ public function run(array $tags, array $options) { $order = !empty($options['sortKey']) ? $options['sortKey'] : 'search_id'; $dir = !empty($options['sortOrder']) ? $options['sortOrder'] : 'desc'; $return = array(); $query = ''; $searchIds = array(); /* Format query */ if (!empty($options['meta_parent_id'])) { $this->sphinxClient->SetFilter('tag_meta_parent_id', is_array($options['meta_parent_id']) ? IPSLib::cleanIntArray($options['meta_parent_id']) : $options['meta_parent_id']); } if (!empty($options['meta_id'])) { $this->sphinxClient->SetFilter('tag_meta_id', is_array($options['meta_id']) ? IPSLib::cleanIntArray($options['meta_id']) : $options['meta_id']); } if (isset($options['meta_app'])) { $query .= ' @tag_meta_app ' . (is_array($options['meta_app']) ? implode("|", $options['meta_app']) : $options['meta_app']) . ''; } if (isset($options['meta_area'])) { if (is_array($options['meta_area'])) { $_areas = array(); foreach ($options['meta_area'] as $v) { $_areas[] = str_replace('-', '_', $v); } $options['meta_area'] = $_areas; } $query .= ' @tag_meta_area ' . (is_array($options['meta_area']) ? implode("|", $options['meta_area']) : str_replace('-', '_', $options['meta_area'])) . ''; } if (!empty($options['not_meta_id'])) { $this->sphinxClient->SetFilter('tag_meta_id', is_array($options['not_meta_id']) ? IPSLib::cleanIntArray($options['not_meta_id']) : array($options['not_meta_id']), true); } if (isset($tags)) { if (is_array($tags)) { foreach ($tags as $key => $tag) { $tags[$key] = $this->sphinxClient->EscapeString($tag); } } else { $tags = $this->sphinxClient->EscapeString($tags); } if (isset($options['match']) and $options['match'] == 'loose') { $query .= ' @tag_text (' . (is_array($tags) ? implode(" | ", $tags) : $tags) . ')'; } else { $query .= ' @tag_text "^' . (is_array($tags) ? implode('$" | "^', $tags) : $tags) . '$"'; } } /* Did we add in perm check? */ if (!empty($options['isViewable'])) { $query .= ' @tag_perm_text ",' . implode('," | ",', $this->member->perm_id_array) . ',"'; $this->sphinxClient->SetFilter('tag_perm_visible', array(1)); } /* Sort */ if ($dir == 'asc') { $this->sphinxClient->SetSortMode(SPH_SORT_ATTR_ASC, str_replace('tg.', '', $order)); } else { $this->sphinxClient->SetSortMode(SPH_SORT_ATTR_DESC, str_replace('tg.', '', $order)); } /* Limit Results */ if (!empty($options['limit']) || !empty($options['offset'])) { $this->sphinxClient->SetLimits(intval($options['offset']), intval($options['limit'])); } /* run it */ $result = $this->sphinxClient->Query($query, $this->settings['sphinx_prefix'] . 'core_tags_search_main,' . $this->settings['sphinx_prefix'] . 'core_tags_search_delta'); $this->logSphinxWarnings(); /* Check matches and fetch data */ if (is_array($result['matches']) && count($result['matches'])) { foreach ($result['matches'] as $res) { $searchIds[] = $res['attrs']['search_id']; } } if (count($searchIds)) { /* Fetch */ if (count($options['joins'])) { $this->DB->build(array('select' => 'tg.*', 'from' => array('core_tags' => 'tg'), 'where' => 'tg.tag_id IN(' . implode(",", $searchIds) . ')', 'add_join' => $options['joins'], 'order' => str_replace('search_id', 'tag_id', $order) . ' ' . $dir)); } else { $this->DB->build(array('select' => '*', 'from' => 'core_tags', 'where' => 'tag_id IN(' . implode(",", $searchIds) . ')', 'add_join' => $options['joins'], 'order' => str_replace('search_id', 'tag_id', $order) . ' ' . $dir)); } $this->DB->execute(); while ($row = $this->DB->fetch()) { $return[$row['tag_id']] = $row; } } return $return; }
/** * Does search * * @access private * @param string $search_term * @param array $limit_clause The erray should be array( begin, end ) * @param string $sort_by Either relevance or date * @param string [$group_by] Field to group on * @param bool [$count_only] Set to true for a count(*) query * @param bool [$content_title_only] Only search titles * @return array **/ private function _searchQuery($search_term, $limit_clause, $sort_by, $group_by = '', $count_only = false, $content_title_only = false) { /* Do we only need to count results? */ if (!$count_only) { if ($limit_clause[1]) { /* Limit Results */ $this->sphinxClient->SetLimits(intval($limit_clause[0]), intval($limit_clause[1])); } else { if ($limit_clause[0]) { $this->sphinxClient->SetLimits(0, intval($limit_clause[0])); } } /* Sort By */ if (isset($sort_by) && in_array($sort_by, array('date', 'relevance'))) { if ($sort_by == 'date') { if ($this->request['search_sort_order'] == 0) { $this->sphinxClient->SetSortMode(SPH_SORT_ATTR_DESC, $this->appSearchPlugin->getDateField()); } else { $this->sphinxClient->SetSortMode(SPH_SORT_ATTR_ASC, $this->appSearchPlugin->getDateField()); } } else { $this->sphinxClient->SetSortMode(SPH_SORT_RELEVANCE); } } else { $this->sphinxClient->SetSortMode(SPH_SORT_RELEVANCE); } } /* Exclude Apps */ if (count($this->exclude_apps)) { $app_id_exclude = array(); foreach ($this->exclude_apps as $app_dir) { $app_id_exclude[] = ipsRegistry::$applications[$app_dir]['app_id']; } $this->sphinxClient->SetFilter('app', $app_id_exclude, TRUE); } /* Permissions */ $perm_array = $this->member->perm_id_array; $perm_array[] = 0; /* Need to remove empty values... */ $final_perms = array(); foreach ($perm_array as $perm_id) { if (is_numeric($perm_id)) { $final_perms[] = $perm_id; } } $this->sphinxClient->SetFilter('perm_view', $final_perms); /* Exclude some items */ if (!$this->memberData['g_is_supmod']) { /* Owner only */ $this->sphinxClient->SetFilter('owner_only', array(0, $this->memberData['member_id'])); /* Friend only */ $this->DB->build(array('select' => 'friends_member_id', 'from' => 'profile_friends', 'where' => "friends_friend_id={$this->memberData['member_id']}")); $this->DB->execute(); $friends_ids = array(0); while ($r = $this->DB->fetch()) { $friends_ids[] = $r['friends_member_id']; } $this->sphinxClient->SetFilter('friend_only', $friends_ids); /* Authorized users only */ $this->sphinxClient->SetFilter('authorized_users', array(0, $this->memberData['member_id'])); } /* Loop through all the search plugins and let them modify the search query */ foreach (ipsRegistry::$applications as $app) { if (IPSSearchIndex::appisSearchable($app['app_directory'])) { if (!isset($this->display_plugins[$app['app_directory']]) || !$this->display_plugins[$app['app_directory']]) { require_once IPSLib::getAppDir($app['app_directory']) . '/extensions/searchDisplay.php'; $_class = $app['app_directory'] . 'SearchDisplay'; $this->display_plugins[$app['app_directory']] = new $_class(); } $this->display_plugins[$app['app_directory']]->search_plugin = $this->appSearchPlugin; if (method_exists($this->display_plugins[$app['app_directory']], 'modifySearchQuery')) { /* Get the modified query */ $this->display_plugins[$app['app_directory']]->modifySearchQuery($this->sphinxClient, $count_only); } } } $groupby = $this->request['show_as_titles'] ? true : false; /* Perform the search */ if (method_exists($this->display_plugins[$this->request['search_app']], 'runSearchQuery')) { $result = $this->display_plugins[$this->request['search_app']]->runSearchQuery($this->sphinxClient, $search_term, $groupby); } else { if ($groupby) { $this->sphinxClient->SetGroupBy('search_id', SPH_GROUPBY_ATTR, '@group DESC'); } $result = $this->sphinxClient->Query($search_term, $this->request['search_app'] . '_search_main,' . $this->request['search_app'] . '_search_delta'); } /* Return the total number of results */ if ($count_only) { return $result['total']; } else { $search_ids = array(); if (is_array($result['matches']) && count($result['matches'])) { foreach ($result['matches'] as $res) { $search_ids[] = $res['attrs']['search_id']; } } return $search_ids; } }