Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
/**
 * 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;
}
Ejemplo n.º 4
0
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);
}