/** * 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; }
$(function () { // initialise picker $("div#friends-picker<?php echo $friendspicker; ?> ").friendsPicker(<?php echo $friendspicker; ?> ); // manually add class to corresponding tab for panels that have content <?php if (sizeof($activeletters) > 0) { $chararray .= "*"; foreach ($activeletters as $letter) { $tab = elgg_strpos($chararray, $letter) + 1; ?> $("div#friends-picker-navigation<?php echo $friendspicker; ?> li.tab<?php echo $tab; ?> a").addClass("tabHasContent"); <?php } } ?> }); }); </script>