/** * Builds the advanced search form * * @access public * @param string Message * @return void */ public function searchAdvancedForm($msg = '', $removed_search_terms = array()) { /* Get any application specific filters */ $filters_html = ''; foreach (ipsRegistry::$applications as $app) { if (IPSSearchIndex::appisSearchable($app['app_directory'])) { require_once IPSLib::getAppDir($app['app_directory']) . '/extensions/searchDisplay.php'; $_class = $app['app_directory'] . 'SearchDisplay'; if (class_exists($_class)) { $search_display_plugin = new $_class(); $filters_html .= $search_display_plugin->getFilterHTML(); } } } /* Output */ $this->title = $this->lang->words['search_form']; $this->registry->output->addNavigation($this->lang->words['search_form'], ''); $this->output .= $this->registry->output->getTemplate('search')->searchAdvancedForm($filters_html, $msg, $removed_search_terms); }
/** * 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; } }
/** * Builds an array that can be used in build * * @access public * @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] Set to true to only search titles * @return array */ private function _buildSearchQueryArray($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 ($group_by) { $group_by = 'i.' . $group_by; } $search_query_array = array('select' => 'COUNT(*) as total_results', 'from' => array('search_index' => 'i'), 'where' => $this->_buildWhereStatement($search_term, $content_title_only), 'group' => $group_by, 'add_join' => array(array('from' => array('permission_index' => 'p'), 'where' => 'p.perm_type_id=i.type_id AND p.perm_type=i.type', 'type' => 'left'), array('from' => array('profile_friends' => 'friend'), 'where' => 'friend.friends_member_id=i.member_id AND friend.friends_friend_id=' . $this->memberData['member_id'], 'type' => 'left'))); } else { /* Sort By */ if (isset($sort_by) && in_array($sort_by, array('date', 'relevance', 'ascdate'))) { $_ord = strstr($sort_by, 'asc') ? 'ASC' : 'DESC'; $order = $sort_by == 'date' ? 'i.updated ' . $_ord : 'ranking' . $_ord; } else { $order = 'ranking DESC'; } /* If there is no search term, we need to force search by updated */ if (!$search_term) { $order = 'i.updated DESC'; } if ($group_by) { $group_by = 'i.' . $group_by; } if ($content_title_only) { $ranking_select = $search_term ? ", MATCH( i.content_title ) AGAINST( '{$search_term}' IN BOOLEAN MODE ) as ranking" : ''; } else { $ranking_select = $search_term ? ", MATCH( i.content, i.content_title ) AGAINST( '{$search_term}' IN BOOLEAN MODE ) as ranking" : ''; } /* Build the search query array */ $search_query_array = array('select' => "i.*{$ranking_select}", 'from' => array('search_index' => 'i'), 'where' => $this->_buildWhereStatement($search_term, $content_title_only), 'limit' => $limit_clause, 'group' => $group_by, 'order' => $order, 'add_join' => array(array('select' => 'p.perm_view', 'from' => array('permission_index' => 'p'), 'where' => 'p.perm_type_id=i.type_id AND p.perm_type=i.type', 'type' => 'left'), array('select' => 'm.members_display_name, m.member_group_id, m.mgroup_others', 'from' => array('members' => 'm'), 'where' => 'i.member_id=m.member_id', 'type' => 'left'), array('from' => array('profile_friends' => 'friend'), 'where' => 'friend.friends_member_id=i.member_id AND friend.friends_friend_id=' . $this->memberData['member_id'], 'type' => 'left'))); } /* 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(); } if (method_exists($this->display_plugins[$app['app_directory']], 'modifySearchQuery')) { /* Get the modified query */ $new_query = $this->display_plugins[$app['app_directory']]->modifySearchQuery($search_query_array, $count_only); /* Simple check to prevent accidentaly breaking the query, clearly not fool proof :) */ $search_query_array = is_array($new_query) && count($new_query) ? $new_query : $search_query_array; } } } return $search_query_array; }