Exemplo n.º 1
0
<?php

$query = elgg_extract('query', $vars, '');
$count = elgg_extract('count', $vars);
$highlight_query = elgg_extract('highlight_query', $vars, true);
// highlight search terms
if (!empty($query)) {
    if ($highlight_query) {
        $searched_words = search_remove_ignored_words($query, 'array');
        $query = search_highlight_words($searched_words, $query);
    }
    $query = "\"{$query}\"";
}
echo elgg_echo('search_advanced:results:title', [$count, $query]);
/**
 * Return a string with highlighted matched queries and relevant context
 * Determins context based upon occurance and distance of words with each other.
 *
 * @param string $haystack
 * @param string $query
 * @param int $min_match_context = 30
 * @param int $max_length = 300
 * @return string
 */
function search_get_highlighted_relevant_substrings($haystack, $query, $min_match_context = 30, $max_length = 300)
{
    global $CONFIG;
    $haystack = strip_tags($haystack);
    $haystack_length = elgg_strlen($haystack);
    $haystack_lc = elgg_strtolower($haystack);
    $words = search_remove_ignored_words($query, 'array');
    // if haystack < $max_length return the entire haystack w/formatting immediately
    if ($haystack_length <= $max_length) {
        $return = search_highlight_words($words, $haystack);
        return $return;
    }
    // get the starting positions and lengths for all matching words
    $starts = array();
    $lengths = array();
    foreach ($words as $word) {
        $word = elgg_strtolower($word);
        $count = elgg_substr_count($haystack_lc, $word);
        $word_len = elgg_strlen($word);
        // find the start positions for the words
        if ($count > 1) {
            $offset = 0;
            while (FALSE !== ($pos = elgg_strpos($haystack_lc, $word, $offset))) {
                $start = $pos - $min_match_context > 0 ? $pos - $min_match_context : 0;
                $starts[] = $start;
                $stop = $pos + $word_len + $min_match_context;
                $lengths[] = $stop - $start;
                $offset += $pos + $word_len;
            }
        } else {
            $pos = elgg_strpos($haystack_lc, $word);
            $start = $pos - $min_match_context > 0 ? $pos - $min_match_context : 0;
            $starts[] = $start;
            $stop = $pos + $word_len + $min_match_context;
            $lengths[] = $stop - $start;
        }
    }
    $offsets = search_consolidate_substrings($starts, $lengths);
    // figure out if we can adjust the offsets and lengths
    // in order to return more context
    $total_length = array_sum($offsets);
    $add_length = 0;
    if ($total_length < $max_length) {
        $add_length = floor(($max_length - $total_length) / count($offsets) / 2);
        $starts = array();
        $lengths = array();
        foreach ($offsets as $offset => $length) {
            $start = $offset - $add_length > 0 ? $offset - $add_length : 0;
            $length = $length + $add_length;
            $starts[] = $start;
            $lengths[] = $length;
        }
        $offsets = search_consolidate_substrings($starts, $lengths);
    }
    // sort by order of string size descending (which is roughly
    // the proximity of matched terms) so we can keep the
    // substrings with terms closest together and discard
    // the others as needed to fit within $max_length.
    arsort($offsets);
    $return_strs = array();
    $total_length = 0;
    foreach ($offsets as $start => $length) {
        $string = trim(elgg_substr($haystack, $start, $length));
        // continue past if adding this substring exceeds max length
        if ($total_length + $length > $max_length) {
            continue;
        }
        $total_length += $length;
        $return_strs[$start] = $string;
    }
    // put the strings in order of occurence
    ksort($return_strs);
    // add ...s where needed
    $return = implode('...', $return_strs);
    if (!array_key_exists(0, $return_strs)) {
        $return = "...{$return}";
    }
    // add to end of string if last substring doesn't hit the end.
    $starts = array_keys($return_strs);
    $last_pos = $starts[count($starts) - 1];
    if ($last_pos + elgg_strlen($return_strs[$last_pos]) < $haystack_length) {
        $return .= '...';
    }
    $return = search_highlight_words($words, $return);
    return $return;
}
Exemplo n.º 3
0
function index_search()
{
    $entityTypes = array();
    if ($_GET['check']) {
        foreach ($_GET['check'] as $entityType) {
            $entityTypes[] = $entityType;
        }
    }
    // $search_type == all || entities || trigger plugin hook
    $search_type = get_input('search_type', 'all');
    // @todo there is a bug in get_input that makes variables have slashes sometimes.
    // @todo is there an example query to demonstrate ^
    // XSS protection is more important that searching for HTML.
    $query = stripslashes(get_input('index-query', get_input('tag', '')));
    if (function_exists('mb_convert_encoding')) {
        $display_query = mb_convert_encoding($query, 'HTML-ENTITIES', 'UTF-8');
    } else {
        // if no mbstring extension, we just strip characters
        $display_query = preg_replace("/[^-]/", "", $query);
    }
    $display_query = htmlspecialchars($display_query, ENT_QUOTES, 'UTF-8', false);
    // check that we have an actual query
    if (!$query) {
        $title = sprintf(elgg_echo('search:results'), "\"{$display_query}\"");
        $body = elgg_view_title(elgg_echo('search:search_error'));
        $body .= elgg_echo('search:no_query');
        $layout = elgg_view_layout('one_sidebar', array('content' => $body));
        echo elgg_view_page($title, $layout);
        return;
    }
    // get limit and offset.  override if on search dashboard, where only 2
    // of each most recent entity types will be shown.
    $limit = $search_type == 'all' ? 2 : get_input('limit', 10);
    $offset = $search_type == 'all' ? 0 : get_input('offset', 0);
    $order = get_input('order', 'desc');
    if ($order != 'asc' && $order != 'desc') {
        $order = 'desc';
    }
    // set up search params
    $params = array('query' => $query, 'offset' => $offset, 'limit' => $limit, 'sort' => $sort, 'order' => $order, 'search_type' => $search_type, 'type' => $entity_type, 'subtype' => $entity_subtype, 'owner_guid' => $owner_guid, 'container_guid' => $container_guid, 'pagination' => $search_type == 'all' ? FALSE : TRUE);
    $types = get_registered_entity_types();
    //$types['object']
    foreach ($types as $type => $subtypes) {
        //only include subtypes the user wishes to search for
        foreach ($subtypes as $key => $subtype) {
            $flag = false;
            error_log($type . $key . $subtype);
            foreach ($entityTypes as $entityType) {
                if ($subtype == $entityType) {
                    $flag = true;
                }
            }
            if ($flag !== true) {
                //var_dump($types[$type][$key]);
                unset($types[$type][$key]);
                //$types = array_values($types);
            }
        }
        //only include types user wishes to search for - this is only for groups and users as they are not sub types
        $flag = false;
        if ($type != 'object') {
            foreach ($entityTypes as $entityType) {
                if ($type == $entityType) {
                    $flag = true;
                }
            }
            if ($flag !== true) {
                unset($types[$type]);
            }
        }
    }
    // add sidebar items for all and native types
    // @todo should these maintain any existing type / subtype filters or reset?
    $data = htmlspecialchars(http_build_query(array('q' => $query, 'entity_subtype' => $entity_subtype, 'entity_type' => $entity_type, 'owner_guid' => $owner_guid, 'search_type' => 'all')));
    $url = elgg_get_site_url() . "search?{$data}";
    $menu_item = new ElggMenuItem('all', elgg_echo('all'), $url);
    elgg_register_menu_item('page', $menu_item);
    foreach ($types as $type => $subtypes) {
        // @todo when using index table, can include result counts on each of these.
        if (is_array($subtypes) && count($subtypes)) {
            foreach ($subtypes as $subtype) {
                $label = "item:{$type}:{$subtype}";
                $data = htmlspecialchars(http_build_query(array('q' => $query, 'entity_subtype' => $subtype, 'entity_type' => $type, 'owner_guid' => $owner_guid, 'search_type' => 'entities', 'friends' => $friends)));
                $url = elgg_get_site_url() . "search?{$data}";
                $menu_item = new ElggMenuItem($label, elgg_echo($label), $url);
                elgg_register_menu_item('page', $menu_item);
            }
        } else {
            $label = "item:{$type}";
            $data = htmlspecialchars(http_build_query(array('q' => $query, 'entity_type' => $type, 'owner_guid' => $owner_guid, 'search_type' => 'entities', 'friends' => $friends)));
            $url = elgg_get_site_url() . "search?{$data}";
            $menu_item = new ElggMenuItem($label, elgg_echo($label), $url);
            elgg_register_menu_item('page', $menu_item);
        }
    }
    // start the actual search
    $results_html = '';
    if ($search_type == 'all' || $search_type == 'entities') {
        // to pass the correct current search type to the views
        $current_params = $params;
        $current_params['search_type'] = 'entities';
        // foreach through types.
        // if a plugin returns FALSE for subtype ignore it.
        // if a plugin returns NULL or '' for subtype, pass to generic type search function.
        // if still NULL or '' or empty(array()) no results found. (== don't show??)
        foreach ($types as $type => $subtypes) {
            if ($search_type != 'all' && $entity_type != $type) {
                continue;
            }
            if (is_array($subtypes) && count($subtypes)) {
                foreach ($subtypes as $subtype) {
                    // no need to search if we're not interested in these results
                    // @todo when using index table, allow search to get full count.
                    if ($search_type != 'all' && $entity_subtype != $subtype) {
                        continue;
                    }
                    $current_params['subtype'] = $subtype;
                    $current_params['type'] = $type;
                    $results = elgg_trigger_plugin_hook('search', "{$type}:{$subtype}", $current_params, NULL);
                    if ($results === FALSE) {
                        // someone is saying not to display these types in searches.
                        continue;
                    } elseif (is_array($results) && !count($results)) {
                        // no results, but results searched in hook.
                    } elseif (!$results) {
                        // no results and not hooked.  use default type search.
                        // don't change the params here, since it's really a different subtype.
                        // Will be passed to elgg_get_entities().
                        $results = elgg_trigger_plugin_hook('search', $type, $current_params, array());
                    }
                    if (is_array($results['entities']) && $results['count']) {
                        if ($view = search_get_search_view($current_params, 'list')) {
                            $results_html .= elgg_view($view, array('results' => $results, 'params' => $current_params));
                        }
                    }
                }
            }
            // pull in default type entities with no subtypes
            $current_params['type'] = $type;
            $current_params['subtype'] = ELGG_ENTITIES_NO_VALUE;
            $results = elgg_trigger_plugin_hook('search', $type, $current_params, array());
            if ($results === FALSE) {
                // someone is saying not to display these types in searches.
                continue;
            }
            if (is_array($results['entities']) && $results['count']) {
                if ($view = search_get_search_view($current_params, 'list')) {
                    $results_html .= elgg_view($view, array('results' => $results, 'params' => $current_params));
                }
            }
        }
    }
    // highlight search terms
    if ($search_type == 'tags') {
        $searched_words = array($display_query);
    } else {
        $searched_words = search_remove_ignored_words($display_query, 'array');
    }
    $highlighted_query = search_highlight_words($searched_words, $display_query);
    $body = elgg_view_title(elgg_echo('search:results', array("\"{$highlighted_query}\"")));
    if (!$results_html) {
        $body .= elgg_view('search/no_results');
    } else {
        $body .= $results_html;
    }
    // this is passed the original params because we don't care what actually
    // matched (which is out of date now anyway).
    // we want to know what search type it is.
    $layout_view = search_get_search_view($params, 'layout');
    $layout = elgg_view($layout_view, array('params' => $params, 'body' => $body));
    $title = elgg_echo('search:results', array("\"{$display_query}\""));
    echo elgg_view_page($title, $layout);
}
Exemplo n.º 4
0
            if ($results === FALSE) {
                // someone is saying not to display these types in searches.
                continue;
            }
            if (isset($results['entities']) && is_array($results['entities']) && $results['count']) {
                if ($view = search_get_search_view($current_params, 'list')) {
                    $search_result_counters["search_types:" . $type] = $results['count'];
                    $results_html .= elgg_view($view, array('results' => $results, 'params' => $current_params));
                }
            }
        }
    }
}
// highlight search terms
$searched_words = search_remove_ignored_words($display_query, 'array');
$highlighted_query = search_highlight_words($searched_words, $display_query);
$body = elgg_view_title(elgg_echo('search:results', array("\"{$highlighted_query}\"")));
// add search form
if (!elgg_is_xhr()) {
    $body .= elgg_view_form("search_advanced/search", array("action" => "search", "method" => "GET", "disable_security" => true), $params);
}
if (!$results_html) {
    $body .= elgg_view('search/no_results');
} else {
    $body .= $results_html;
}
// moved to bottom so we can use search result count in labels
// add sidebar items for all and native types
// @todo should these maintain any existing type / subtype filters or reset?
// JD: yeah they should
$data = htmlspecialchars(http_build_query(array('q' => $query, 'search_type' => 'all')));
Exemplo n.º 5
0
<?php

$q = sanitise_string(get_input("q"));
$limit = max((int) get_input("limit", 5), 1);
$page_owner_guid = (int) get_input("page_owner_guid");
$result = array();
if (!empty($q)) {
    // keywords (tags, categories)
    $keywords = search_advanced_get_keywords();
    if (!empty($keywords)) {
        foreach ($keywords as $content) {
            if (stristr($content, $q)) {
                $result[] = array("type" => "tag", "content" => search_highlight_words(array($q), $content), "value" => $content, "href" => elgg_normalize_url("search?q=" . urlencode($content)));
            }
        }
    }
    // look for users
    $options = array();
    $options['query'] = $q;
    $options['type'] = "user";
    $options['limit'] = $limit;
    $results = elgg_trigger_plugin_hook('search', 'user', $options, array());
    $user_count = $results['count'];
    $users = $results['entities'];
    if ($user_count > 0) {
        $result[] = array("type" => "placeholder", "content" => "<label>" . elgg_echo("item:user") . " (" . $user_count . ")</label>", "href" => elgg_normalize_url("search?entity_type=user&search_type=entities&q=" . $q));
        foreach ($users as $user) {
            $result[] = array("type" => "user", "value" => $user->name, "href" => $user->getURL(), "content" => elgg_view("search_advanced/autocomplete/user", array("entity" => $user)));
        }
    }
    // search for groups