function elgg_solr_get_access_query() { if (elgg_is_admin_logged_in() || elgg_get_ignore_access()) { return false; // no access limit } static $return; if ($return) { return $return; } $access = get_access_array(); // access filter query if ($access) { $access_list = implode(' ', $access); } if (elgg_is_logged_in()) { // get friends // @TODO - is there a better way? Not sure if there's a limit on solr if // someone has a whole lot of friends... $friends = elgg_get_entities_from_relationship(array('type' => 'user', 'relationship' => 'friend', 'relationship_guid' => elgg_get_logged_in_user_guid(), 'inverse_relationship' => true, 'limit' => false, 'callback' => false)); $friend_guids = array(); foreach ($friends as $friend) { $friend_guids[] = $friend->guid; } $friends_list = ''; if ($friend_guids) { $friends_list = elgg_solr_escape_special_chars(implode(' ', $friend_guids)); } } //$query->createFilterQuery('access')->setQuery("owner_guid: {guid} OR access_id:({$access_list}) OR (access_id:" . ACCESS_FRIENDS . " AND owner_guid:({$friends}))"); if (elgg_is_logged_in()) { $return = "owner_guid:" . elgg_get_logged_in_user_guid(); } else { $return = ''; } if ($access_list) { if ($return) { $return .= ' OR '; } $return .= "access_id:(" . elgg_solr_escape_special_chars($access_list) . ")"; } $fr_prefix = ''; $fr_suffix = ''; if ($return && $friends_list) { $return .= ' OR '; $fr_prefix = '('; $fr_suffix = ')'; } if ($friends_list) { $return .= $fr_prefix . 'access_id:' . elgg_solr_escape_special_chars(ACCESS_FRIENDS) . ' AND owner_guid:(' . $friends_list . ')' . $fr_suffix; } return $return; }
function elgg_solr_tag_search($hook, $type, $return, $params) { $valid_tag_names = elgg_get_registered_tag_metadata_names(); if (!$valid_tag_names || !is_array($valid_tag_names)) { return array('entities' => array(), 'count' => 0); } // if passed a tag metadata name, only search on that tag name. // tag_name isn't included in the params because it's specific to // tag searches. if ($tag_names = get_input('tag_names')) { if (is_array($tag_names)) { $search_tag_names = $tag_names; } else { $search_tag_names = array($tag_names); } // check these are valid to avoid arbitrary metadata searches. foreach ($search_tag_names as $i => $tag_name) { if (!in_array($tag_name, $valid_tag_names)) { unset($search_tag_names[$i]); } } } else { $search_tag_names = $valid_tag_names; } $query_parts = array(); foreach ($search_tag_names as $tagname) { // @note - these need to be treated as literal exact matches, so encapsulate in double-quotes $query_parts[] = 'tags:"' . elgg_solr_escape_special_chars($tagname . '%%' . $params['query']) . '"'; } if (!$query_parts) { return array('entities' => array(), 'count' => 0); } $q = implode(' OR ', $query_parts); $select = array('query' => $q, 'start' => $params['offset'], 'rows' => $params['limit'], 'fields' => array('id', 'title', 'description', 'score')); if ($params['select'] && is_array($params['select'])) { $select = array_merge($select, $params['select']); } $client = elgg_solr_get_client(); // get an update query instance $query = $client->createSelect($select); $default_sorts = array('score' => 'desc', 'time_created' => 'desc'); $sorts = $params['sorts'] ? $params['sorts'] : $default_sorts; $query->addSorts($sorts); $default_fq = elgg_solr_get_default_fq($params); if ($params['fq']) { $filter_queries = array_merge($default_fq, $params['fq']); } else { $filter_queries = $default_fq; } if (!empty($filter_queries)) { foreach ($filter_queries as $key => $value) { $query->createFilterQuery($key)->setQuery($value); } } // get highlighting component and apply settings $hl = $query->getHighlighting(); $hl->setFields(array('tags')); $hl->setSimplePrefix('<span data-hl="elgg-solr">'); $hl->setSimplePostfix('</span>'); // this executes the query and returns the result try { $resultset = $client->select($query); } catch (Exception $e) { error_log($e->getMessage()); return null; } // Get the highlighted snippet try { $highlighting = $resultset->getHighlighting(); } catch (Exception $e) { error_log($e->getMessage()); return null; } // Count the total number of documents found by solr $count = $resultset->getNumFound(); $hl_prefix = elgg_solr_get_hl_prefix(); $hl_suffix = elgg_solr_get_hl_suffix(); $search_results = array(); $config = HTMLPurifier_Config::createDefault(); $purifier = new HTMLPurifier($config); foreach ($resultset as $document) { $search_results[$document->id] = array(); $snippet = ''; // highlighting results can be fetched by document id (the field defined as uniquekey in this schema) $highlightedDoc = $highlighting->getResult($document->id); if ($highlightedDoc) { foreach ($highlightedDoc as $field => $highlight) { // a little hackery for matched tags $snippet = array(); foreach ($highlight as $key => $h) { $matched = $hl_prefix; $matched .= substr(strstr(elgg_strip_tags($h), '%%'), 2); $matched .= $hl_suffix; $snippet[] = $purifier->purify($matched); } $display = implode(', ', $snippet); $search_results[$document->id][$field] = $display; } } $search_results[$document->id]['score'] = $document->score; } // get the entities $entities = array(); $entities_unsorted = array(); if ($search_results) { $entities_unsorted = elgg_get_entities(array('guids' => array_keys($search_results), 'limit' => false)); } $show_score = elgg_get_plugin_setting('show_score', 'elgg_solr'); foreach ($search_results as $guid => $matches) { foreach ($entities_unsorted as $e) { if ($e->guid == $guid) { $desc_suffix = ''; if ($show_score == 'yes' && elgg_is_admin_logged_in()) { $desc_suffix .= elgg_view('output/longtext', array('value' => elgg_echo('elgg_solr:relevancy', array($matches['score'])), 'class' => 'elgg-subtext')); } $title = $e->title ? $e->title : $e->name; $description = $e->description; $e->setVolatileData('search_matched_title', $title); $e->setVolatileData('search_matched_description', elgg_get_excerpt($description) . $desc_suffix); $e->setVolatileData('search_matched_extra', $matches['tags']); $entities[] = $e; } } } return array('entities' => $entities, 'count' => $count); }
/** * Get access query for Solr search * * @param int $user_guid GUID of the user accessing content * @return string */ function elgg_solr_get_access_query($user_guid = null) { if (elgg_get_ignore_access()) { return ''; } if (!isset($user_guid)) { $user_guid = elgg_get_logged_in_user_guid(); } if (elgg_is_admin_user($user_guid)) { return ''; } $access_public = elgg_solr_escape_special_chars(ACCESS_PUBLIC); $access_friends = elgg_solr_escape_special_chars(ACCESS_FRIENDS); $user_guid = elgg_solr_escape_special_chars($user_guid); $queries = []; if ($user_guid) { $queries['ors']['collections'] = "access_id:{!join from=access_list_is to=access_id}id:{$user_guid}"; $queries['ors']['is_owner'] = "owner_guid:{$user_guid}"; $queries['ors']['is_friend'] = "access_id:{$access_friends} AND owner_guid:{!join from=friends_of_is to=owner_guid}id:{$user_guid}"; } else { $queries['ors']['collections'] = "access_id:{$access_public}"; } $params = ['user_guid' => $user_guid]; $queries = elgg_trigger_plugin_hook('elgg_solr:access', 'entities', $params, $queries); if (!empty($queries['ors'])) { $ors = []; foreach ($queries['ors'] as $or) { $ors[] = "({$or})"; } $queries['ands'][] = implode(' OR ', $ors); } $query_str = ''; if (!empty($queries['ands'])) { $ands = []; foreach ($queries['ands'] as $and) { $ands[] = "({$and})"; } $query_str = '(' . implode(' AND ', $ands) . ')'; } return $query_str; }
function plugin_search($hook, $type, $return, $params) { $select = array('start' => $params['offset'], 'rows' => $params['limit'], 'fields' => array('id', 'title', 'description')); if ($params['select'] && is_array($params['select'])) { $select = array_merge($select, $params['select']); } // create a client instance $client = elgg_solr_get_client(); // get an update query instance $query = $client->createSelect($select); $sorts = array('score' => 'desc', 'time_created' => 'desc'); if ($params['sorts'] && is_array($params['sorts'])) { $sorts = $params['sorts']; } $query->addSorts($sorts); $title_boost = elgg_solr_get_title_boost(); $description_boost = elgg_solr_get_description_boost(); // get the dismax component and set a boost query $dismax = $query->getDisMax(); $qf = "title^{$title_boost} description^{$description_boost}"; if ($params['qf']) { $qf = $params['qf']; } $dismax->setQueryFields($qf); $dismax->setQueryAlternative('*:*'); $boostQuery = elgg_solr_get_boost_query(); if ($boostQuery) { $dismax->setBoostQuery($boostQuery); } // this query is now a dismax query $query->setQuery($params['query']); // make sure we're only getting objects:plugin_project $params['fq']['type'] = 'type:object'; $params['fq']['subtype'] = 'subtype:plugin_project'; if (($category = get_input('category')) && $category != 'all') { $params['fq']['plugincat'] = 'tags:"' . elgg_solr_escape_special_chars('plugincat%%' . $category) . '"'; } $default_fq = elgg_solr_get_default_fq($params); if ($params['fq']) { $filter_queries = array_merge($default_fq, $params['fq']); } else { $filter_queries = $default_fq; } if (!empty($filter_queries)) { foreach ($filter_queries as $key => $value) { $query->createFilterQuery($key)->setQuery($value); } } // get highlighting component and apply settings $hl = $query->getHighlighting(); $hl->setFields(array('title', 'description')); $hl->setSimplePrefix('<strong class="search-highlight search-highlight-color1">'); $hl->setSimplePostfix('</strong>'); // this executes the query and returns the result try { $resultset = $client->select($query); } catch (Exception $e) { error_log($e->getMessage()); return null; } // Get the highlighted snippet try { $highlighting = $resultset->getHighlighting(); } catch (Exception $e) { error_log($e->getMessage()); return null; } // Count the total number of documents found by solr $count = $resultset->getNumFound(); $search_results = array(); foreach ($resultset as $document) { $search_results[$document->id] = array(); $snippet = ''; // highlighting results can be fetched by document id (the field defined as uniquekey in this schema) $highlightedDoc = $highlighting->getResult($document->id); if ($highlightedDoc) { foreach ($highlightedDoc as $field => $highlight) { $snippet = implode(' (...) ', $highlight); $snippet = search_get_highlighted_relevant_substrings(elgg_strip_tags($snippet), $params['query']); $search_results[$document->id][$field] = $snippet; } } } // get the entities $entities = array(); $entities_unsorted = array(); if ($search_results) { $entities_unsorted = elgg_get_entities(array('guids' => array_keys($search_results), 'limit' => false)); } foreach ($search_results as $guid => $matches) { foreach ($entities_unsorted as $e) { if ($e->guid == $guid) { if ($matches['title']) { $e->setVolatileData('search_matched_title', $matches['title']); } else { $e->setVolatileData('search_matched_title', $e->title); } if ($matches['description']) { $e->setVolatileData('search_matched_description', $matches['description']); } else { $e->setVolatileData('search_matched_description', elgg_get_excerpt($e->description, 100)); } $entities[] = $e; } } } return array('entities' => $entities, 'count' => $count); }