Version Description
- Tokenizer was using
strlen()and notmb_strlen(), so word lengths were not calculated properly. If your site uses non-ASCII alphabet, rebuilding the index is a good idea. - Small improvement to WPML multilanguage filtering.
-
relevanssi_the_title()got a new parameter: if you don't want to echo the title, you can use it likerelevanssi_the_title(false)to make it return the title. - Relevanssi had
the_titlefilter hook calls that were missing the second parameter; that's now fixed. - The excerpt-building algorithm is completely rewritten based on work by Ben Boyter (http://www.boyter.org/).
- The
[watupro]shortcode didn't work with Relevanssi, so Relevanssi will now bypass it. - The plugin i18n features have been improved slightly.
- New filter:
relevanssi_didyoumean_suggestionlets you modify the Did you mean? suggestion before it's displayed. -
relevanssi_didyoumean()has a new parameter: you can now choose whether the result is echoed out (the default value) or just returned. - In the search results breakdown, you can now use %categories% and %taxonomies% to show the number of matches in categories and taxonomies other than tags and cats, respectively.
- Relevanssi supports
fieldsparameter (bothidsandid=>parent) to return only post IDs or post IDs and post parents.
Download this release
Release Info
| Developer | msaari |
| Plugin | |
| Version | 3.5 |
| Comparing to | |
| See all releases | |
Code changes from version 3.4.2 to 3.5
- lib/common.php +25 -14
- lib/excerpts-highlights.php +129 -128
- lib/indexing.php +3 -1
- lib/init.php +2 -3
- lib/interface.php +11 -11
- lib/search.php +48 -11
- lib/shortcodes.php +1 -1
- readme.txt +18 -2
- relevanssi.php +5 -6
lib/common.php
CHANGED
|
@@ -15,7 +15,7 @@ function relevanssi_wpml_filter($data) {
|
|
| 15 |
|
| 16 |
if (function_exists('icl_object_id') && !function_exists('pll_is_translated_post_type')) {
|
| 17 |
if ($sitepress->is_translated_post_type($hit->post_type)) {
|
| 18 |
-
if ($hit->ID == icl_object_id($hit->ID, $hit->post_type, false,
|
| 19 |
}
|
| 20 |
else {
|
| 21 |
$filtered_hits[] = $hit;
|
|
@@ -355,7 +355,7 @@ function relevanssi_strip_invisibles($text) {
|
|
| 355 |
}
|
| 356 |
|
| 357 |
function relevanssi_strlen_sort($a, $b) {
|
| 358 |
-
return
|
| 359 |
}
|
| 360 |
|
| 361 |
function relevanssi_get_custom_fields() {
|
|
@@ -387,7 +387,12 @@ function relevanssi_mb_trim($string) {
|
|
| 387 |
}
|
| 388 |
|
| 389 |
function relevanssi_remove_punct($a) {
|
| 390 |
-
$a =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 391 |
$a = stripslashes($a);
|
| 392 |
|
| 393 |
$a = str_replace('ß', 'ss', $a);
|
|
@@ -493,7 +498,8 @@ function relevanssi_tokenize($str, $remove_stops = true, $min_word_length = -1)
|
|
| 493 |
while ($t !== false) {
|
| 494 |
$t = strval($t);
|
| 495 |
$accept = true;
|
| 496 |
-
|
|
|
|
| 497 |
$t = strtok("\n\t ");
|
| 498 |
continue;
|
| 499 |
}
|
|
@@ -638,13 +644,9 @@ function relevanssi_add_synonyms($q) {
|
|
| 638 |
/* Helper function that does mb_stripos, falls back to mb_strpos and mb_strtoupper
|
| 639 |
* if that cannot be found, and falls back to just strpos if even that is not possible.
|
| 640 |
*/
|
| 641 |
-
function relevanssi_stripos($content, $term, $offset) {
|
| 642 |
-
if (
|
| 643 |
-
|
| 644 |
-
}
|
| 645 |
-
else {
|
| 646 |
-
if ($offset > strlen($content)) return false;
|
| 647 |
-
}
|
| 648 |
if (function_exists('mb_stripos')) {
|
| 649 |
$pos = ("" == $content) ? false : mb_stripos($content, $term, $offset);
|
| 650 |
}
|
|
@@ -682,16 +684,17 @@ function relevanssi_close_tags($html) {
|
|
| 682 |
|
| 683 |
/* Prints out post title with highlighting.
|
| 684 |
*/
|
| 685 |
-
function relevanssi_the_title() {
|
| 686 |
global $post;
|
| 687 |
if (empty($post->post_highlighted_title)) $post->post_highlighted_title = $post->post_title;
|
| 688 |
-
echo $post->post_highlighted_title;
|
|
|
|
| 689 |
}
|
| 690 |
|
| 691 |
/* Returns the post title with highlighting.
|
| 692 |
*/
|
| 693 |
function relevanssi_get_the_title($post_id) {
|
| 694 |
-
$post =
|
| 695 |
if (empty($post->post_highlighted_title)) $post->post_highlighted_title = $post->post_title;
|
| 696 |
return $post->post_highlighted_title;
|
| 697 |
}
|
|
@@ -704,4 +707,12 @@ function relevanssi_update_doc_count( $values, $post ) {
|
|
| 704 |
}
|
| 705 |
return $values;
|
| 706 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 707 |
?>
|
| 15 |
|
| 16 |
if (function_exists('icl_object_id') && !function_exists('pll_is_translated_post_type')) {
|
| 17 |
if ($sitepress->is_translated_post_type($hit->post_type)) {
|
| 18 |
+
if ($hit->ID == icl_object_id($hit->ID, $hit->post_type, false, $sitepress->get_current_language())) $filtered_hits[] = $hit;
|
| 19 |
}
|
| 20 |
else {
|
| 21 |
$filtered_hits[] = $hit;
|
| 355 |
}
|
| 356 |
|
| 357 |
function relevanssi_strlen_sort($a, $b) {
|
| 358 |
+
return relevanssi_strlen($b) - relevanssi_strlen($a);
|
| 359 |
}
|
| 360 |
|
| 361 |
function relevanssi_get_custom_fields() {
|
| 387 |
}
|
| 388 |
|
| 389 |
function relevanssi_remove_punct($a) {
|
| 390 |
+
$a = preg_replace ('/<[^>]*>/', ' ', $a);
|
| 391 |
+
|
| 392 |
+
$a = str_replace("\r", '', $a); // --- replace with empty space
|
| 393 |
+
$a = str_replace("\n", ' ', $a); // --- replace with space
|
| 394 |
+
$a = str_replace("\t", ' ', $a); // --- replace with space
|
| 395 |
+
|
| 396 |
$a = stripslashes($a);
|
| 397 |
|
| 398 |
$a = str_replace('ß', 'ss', $a);
|
| 498 |
while ($t !== false) {
|
| 499 |
$t = strval($t);
|
| 500 |
$accept = true;
|
| 501 |
+
|
| 502 |
+
if (relevanssi_strlen($t) < $min_word_length) {
|
| 503 |
$t = strtok("\n\t ");
|
| 504 |
continue;
|
| 505 |
}
|
| 644 |
/* Helper function that does mb_stripos, falls back to mb_strpos and mb_strtoupper
|
| 645 |
* if that cannot be found, and falls back to just strpos if even that is not possible.
|
| 646 |
*/
|
| 647 |
+
function relevanssi_stripos($content, $term, $offset = 0) {
|
| 648 |
+
if ($offset > relevanssi_strlen($content)) return false;
|
| 649 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
| 650 |
if (function_exists('mb_stripos')) {
|
| 651 |
$pos = ("" == $content) ? false : mb_stripos($content, $term, $offset);
|
| 652 |
}
|
| 684 |
|
| 685 |
/* Prints out post title with highlighting.
|
| 686 |
*/
|
| 687 |
+
function relevanssi_the_title($echo = true) {
|
| 688 |
global $post;
|
| 689 |
if (empty($post->post_highlighted_title)) $post->post_highlighted_title = $post->post_title;
|
| 690 |
+
if ($echo) echo $post->post_highlighted_title;
|
| 691 |
+
return $post->post_highlighted_title;
|
| 692 |
}
|
| 693 |
|
| 694 |
/* Returns the post title with highlighting.
|
| 695 |
*/
|
| 696 |
function relevanssi_get_the_title($post_id) {
|
| 697 |
+
$post = relevanssi_get_post($post_id);
|
| 698 |
if (empty($post->post_highlighted_title)) $post->post_highlighted_title = $post->post_title;
|
| 699 |
return $post->post_highlighted_title;
|
| 700 |
}
|
| 707 |
}
|
| 708 |
return $values;
|
| 709 |
}
|
| 710 |
+
|
| 711 |
+
/* Uses mb_strlen() if available, otherwise falls back to strlen().
|
| 712 |
+
*/
|
| 713 |
+
function relevanssi_strlen($s) {
|
| 714 |
+
if ( function_exists( 'mb_strlen' ) ) return mb_strlen( $s );
|
| 715 |
+
return strlen( $s );
|
| 716 |
+
}
|
| 717 |
+
|
| 718 |
?>
|
lib/excerpts-highlights.php
CHANGED
|
@@ -18,7 +18,7 @@ function relevanssi_do_excerpt($t_post, $query) {
|
|
| 18 |
if ($post != NULL) $old_global_post = $post;
|
| 19 |
$post = $t_post;
|
| 20 |
|
| 21 |
-
$remove_stopwords =
|
| 22 |
$terms = relevanssi_tokenize($query, $remove_stopwords, -1);
|
| 23 |
|
| 24 |
// These shortcodes cause problems with Relevanssi excerpts
|
|
@@ -60,7 +60,7 @@ function relevanssi_do_excerpt($t_post, $query) {
|
|
| 60 |
}
|
| 61 |
}
|
| 62 |
}
|
| 63 |
-
|
| 64 |
$start = $excerpt_data[2];
|
| 65 |
|
| 66 |
$excerpt = $excerpt_data[0];
|
|
@@ -113,7 +113,7 @@ function relevanssi_create_excerpt($content, $terms, $query) {
|
|
| 113 |
$best_excerpt_term_hits = -1;
|
| 114 |
$excerpt = "";
|
| 115 |
|
| 116 |
-
$content = preg_replace('/\s+/', ' ', $content);
|
| 117 |
$content = " $content";
|
| 118 |
|
| 119 |
$phrases = relevanssi_extract_phrases(stripslashes($query));
|
|
@@ -131,89 +131,13 @@ function relevanssi_create_excerpt($content, $terms, $query) {
|
|
| 131 |
$terms[$phrase] = 1;
|
| 132 |
}
|
| 133 |
|
|
|
|
| 134 |
uksort($terms, 'relevanssi_strlen_sort');
|
| 135 |
|
| 136 |
$start = false;
|
| 137 |
if ("chars" == $type) {
|
| 138 |
-
$
|
| 139 |
-
|
| 140 |
-
$term = trim($term);
|
| 141 |
-
$term_key = $term;
|
| 142 |
-
get_option('relevanssi_fuzzy') != 'none' ? $term = "$term" : $term = " $term";
|
| 143 |
-
|
| 144 |
-
$pos = 0;
|
| 145 |
-
$n = 0;
|
| 146 |
-
while (false !== $pos) {
|
| 147 |
-
$pos = relevanssi_stripos($content, $term, $pos);
|
| 148 |
-
if (false !== $pos) {
|
| 149 |
-
$term_positions[$pos] = $term_key;
|
| 150 |
-
function_exists('mb_strlen') ? $pos = $pos + mb_strlen($term) : $pos = $pos + strlen(utf8_decode($term));
|
| 151 |
-
}
|
| 152 |
-
}
|
| 153 |
-
}
|
| 154 |
-
ksort($term_positions);
|
| 155 |
-
$positions = array_keys($term_positions);
|
| 156 |
-
$best_position = 0;
|
| 157 |
-
$best_position_hits = 0;
|
| 158 |
-
$quarter = floor($excerpt_length/4); // adjustment, so the excerpt doesn't start with the search term
|
| 159 |
-
for ($i = 0; $i < count($positions); $i++) {
|
| 160 |
-
$key = $positions[$i];
|
| 161 |
-
$orig_key = $key;
|
| 162 |
-
$key = $key - $quarter;
|
| 163 |
-
if ($key < 0) $key = 0;
|
| 164 |
-
|
| 165 |
-
$j = $i + 1;
|
| 166 |
-
|
| 167 |
-
$this_excerpt_terms = array();
|
| 168 |
-
|
| 169 |
-
if (isset($term_positions[$orig_key])) $this_excerpt_terms[$term_positions[$orig_key]] = true;
|
| 170 |
-
|
| 171 |
-
while (isset($positions[$j])) {
|
| 172 |
-
if (isset($positions[$j])) {
|
| 173 |
-
$next_key = $positions[$j];
|
| 174 |
-
}
|
| 175 |
-
|
| 176 |
-
if ($key + $excerpt_length > $next_key) {
|
| 177 |
-
$this_excerpt_terms[$term_positions[$next_key]] = true;
|
| 178 |
-
}
|
| 179 |
-
else {
|
| 180 |
-
break; // farther than the excerpt length
|
| 181 |
-
}
|
| 182 |
-
$j++;
|
| 183 |
-
}
|
| 184 |
-
|
| 185 |
-
if (count($this_excerpt_terms) > $best_position_hits) {
|
| 186 |
-
$best_position_hits = count($this_excerpt_terms);
|
| 187 |
-
$best_position = $key;
|
| 188 |
-
}
|
| 189 |
-
}
|
| 190 |
-
|
| 191 |
-
if ($best_position + $excerpt_length < strlen($content)) {
|
| 192 |
-
if (function_exists('mb_substr'))
|
| 193 |
-
$excerpt = mb_substr($content, $best_position, $excerpt_length);
|
| 194 |
-
else
|
| 195 |
-
$excerpt = substr($content, $best_position, $excerpt_length);
|
| 196 |
-
}
|
| 197 |
-
else {
|
| 198 |
-
$fixed_position = strlen($content) - $excerpt_length;
|
| 199 |
-
if ($fixed_position > 0) {
|
| 200 |
-
if (function_exists('mb_substr'))
|
| 201 |
-
$excerpt = mb_substr($content, $fixed_position, $excerpt_length);
|
| 202 |
-
else
|
| 203 |
-
$excerpt = substr($content, $fixed_position, $excerpt_length);
|
| 204 |
-
}
|
| 205 |
-
}
|
| 206 |
-
|
| 207 |
-
if ($best_position == 0) $start = true;
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
if ("" == $excerpt) {
|
| 211 |
-
if (function_exists('mb_substr'))
|
| 212 |
-
$excerpt = mb_substr($content, 0, $excerpt_length);
|
| 213 |
-
else
|
| 214 |
-
$excerpt = substr($content, 0, $excerpt_length);
|
| 215 |
-
$start = true;
|
| 216 |
-
}
|
| 217 |
}
|
| 218 |
else {
|
| 219 |
$words = explode(' ', $content);
|
|
@@ -230,51 +154,11 @@ function relevanssi_create_excerpt($content, $terms, $query) {
|
|
| 230 |
|
| 231 |
$excerpt_slice = " $excerpt_slice";
|
| 232 |
$term_hits = 0;
|
| 233 |
-
|
| 234 |
-
$term = " $term";
|
| 235 |
-
if (function_exists('mb_stripos')) {
|
| 236 |
-
$pos = ("" == $excerpt_slice) ? false : mb_stripos($excerpt_slice, $term);
|
| 237 |
-
// To avoid "empty haystack" warnings
|
| 238 |
-
}
|
| 239 |
-
else if (function_exists('mb_strpos')) {
|
| 240 |
-
$pos = mb_strpos($excerpt_slice, $term);
|
| 241 |
-
if (false === $pos) {
|
| 242 |
-
if (function_exists('mb_strtoupper') && function_exists('mb_strpos') && function_exists('mb_substr')) {
|
| 243 |
-
$titlecased = mb_strtoupper(mb_substr($term, 0, 1)) . mb_substr($term, 1);
|
| 244 |
-
$pos = mb_strpos($excerpt_slice, $titlecased);
|
| 245 |
-
if (false === $pos) {
|
| 246 |
-
$pos = mb_strpos($excerpt_slice, mb_strtoupper($term));
|
| 247 |
-
}
|
| 248 |
-
}
|
| 249 |
-
else {
|
| 250 |
-
$titlecased = strtoupper(substr($term, 0, 1)) . substr($term, 1);
|
| 251 |
-
$pos = strpos($excerpt_slice, $titlecased);
|
| 252 |
-
if (false === $pos) {
|
| 253 |
-
$pos = strpos($excerpt_slice, strtoupper($term));
|
| 254 |
-
}
|
| 255 |
-
}
|
| 256 |
-
}
|
| 257 |
-
}
|
| 258 |
-
else {
|
| 259 |
-
$pos = strpos($excerpt_slice, $term);
|
| 260 |
-
if (false === $pos) {
|
| 261 |
-
$titlecased = strtoupper(substr($term, 0, 1)) . substr($term, 1);
|
| 262 |
-
$pos = strpos($excerpt_slice, $titlecased);
|
| 263 |
-
if (false === $pos) {
|
| 264 |
-
$pos = strpos($excerpt_slice, strtoupper($term));
|
| 265 |
-
}
|
| 266 |
-
}
|
| 267 |
-
}
|
| 268 |
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
if ($term_hits > $best_excerpt_term_hits) {
|
| 274 |
-
$best_excerpt_term_hits = $term_hits;
|
| 275 |
-
$excerpt = $excerpt_slice;
|
| 276 |
-
}
|
| 277 |
-
}
|
| 278 |
}
|
| 279 |
|
| 280 |
$i += $excerpt_length;
|
|
@@ -374,7 +258,8 @@ function relevanssi_highlight_terms($excerpt, $query) {
|
|
| 374 |
|
| 375 |
if ( function_exists('mb_internal_encoding') )
|
| 376 |
mb_internal_encoding("UTF-8");
|
| 377 |
-
|
|
|
|
| 378 |
$terms = array_keys(relevanssi_tokenize($query, $remove_stopwords = true, $min_word_length = -1));
|
| 379 |
|
| 380 |
if (is_array($query)) $query = implode(' ', $query); // just in case
|
|
@@ -403,7 +288,9 @@ function relevanssi_highlight_terms($excerpt, $query) {
|
|
| 403 |
$excerpt = html_entity_decode($excerpt);
|
| 404 |
|
| 405 |
if ($word_boundaries) {
|
| 406 |
-
get_option('relevanssi_fuzzy') != 'none' ? $regex = "/($pr_term)(?!(^&+)?(;))/iu" : $regex = "/(\b$pr_term|$pr_term\b)(?!(^&+)?(;))/iu";
|
|
|
|
|
|
|
| 407 |
$excerpt = preg_replace($regex, $start_emp_token . '\\1' . $end_emp_token, $excerpt);
|
| 408 |
if (empty($excerpt)) $excerpt = preg_replace($regex, $start_emp_token . '\\1' . $end_emp_token, $undecoded_excerpt);
|
| 409 |
}
|
|
@@ -493,4 +380,118 @@ function relevanssi_remove_nested_highlights($s, $a, $b) {
|
|
| 493 |
return $whole;
|
| 494 |
}
|
| 495 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 496 |
?>
|
| 18 |
if ($post != NULL) $old_global_post = $post;
|
| 19 |
$post = $t_post;
|
| 20 |
|
| 21 |
+
$remove_stopwords = true;
|
| 22 |
$terms = relevanssi_tokenize($query, $remove_stopwords, -1);
|
| 23 |
|
| 24 |
// These shortcodes cause problems with Relevanssi excerpts
|
| 60 |
}
|
| 61 |
}
|
| 62 |
}
|
| 63 |
+
|
| 64 |
$start = $excerpt_data[2];
|
| 65 |
|
| 66 |
$excerpt = $excerpt_data[0];
|
| 113 |
$best_excerpt_term_hits = -1;
|
| 114 |
$excerpt = "";
|
| 115 |
|
| 116 |
+
$content = preg_replace('/\s+/u', ' ', $content);
|
| 117 |
$content = " $content";
|
| 118 |
|
| 119 |
$phrases = relevanssi_extract_phrases(stripslashes($query));
|
| 131 |
$terms[$phrase] = 1;
|
| 132 |
}
|
| 133 |
|
| 134 |
+
// longest search terms first, because those are generally more significant
|
| 135 |
uksort($terms, 'relevanssi_strlen_sort');
|
| 136 |
|
| 137 |
$start = false;
|
| 138 |
if ("chars" == $type) {
|
| 139 |
+
$prev_count = floor($excerpt_length / 2);
|
| 140 |
+
list($excerpt, $best_excerpt_term_hits, $start) = relevanssi_extract_relevant(array_keys($terms), $content, $excerpt_length, $prev_count);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
}
|
| 142 |
else {
|
| 143 |
$words = explode(' ', $content);
|
| 154 |
|
| 155 |
$excerpt_slice = " $excerpt_slice";
|
| 156 |
$term_hits = 0;
|
| 157 |
+
$count = relevanssi_count_matches(array_keys($terms), $excerpt_slice);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
|
| 159 |
+
if ($count > 0 && $count > $best_excerpt_term_hits) {
|
| 160 |
+
$best_excerpt_term_hits = $count;
|
| 161 |
+
$excerpt = $excerpt_slice;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
}
|
| 163 |
|
| 164 |
$i += $excerpt_length;
|
| 258 |
|
| 259 |
if ( function_exists('mb_internal_encoding') )
|
| 260 |
mb_internal_encoding("UTF-8");
|
| 261 |
+
|
| 262 |
+
do_action('relevanssi_highlight_tokenize');
|
| 263 |
$terms = array_keys(relevanssi_tokenize($query, $remove_stopwords = true, $min_word_length = -1));
|
| 264 |
|
| 265 |
if (is_array($query)) $query = implode(' ', $query); // just in case
|
| 288 |
$excerpt = html_entity_decode($excerpt);
|
| 289 |
|
| 290 |
if ($word_boundaries) {
|
| 291 |
+
// get_option('relevanssi_fuzzy') != 'none' ? $regex = "/($pr_term)(?!(^&+)?(;))/iu" : $regex = "/(\b$pr_term|$pr_term\b)(?!(^&+)?(;))/iu";
|
| 292 |
+
get_option('relevanssi_fuzzy') != 'none' ? $regex = "/(\b$pr_term|$pr_term\b)(?!(^&+)?(;))/iu" : $regex = "/(\b$pr_term\b)(?!(^&+)?(;))/iu";
|
| 293 |
+
|
| 294 |
$excerpt = preg_replace($regex, $start_emp_token . '\\1' . $end_emp_token, $excerpt);
|
| 295 |
if (empty($excerpt)) $excerpt = preg_replace($regex, $start_emp_token . '\\1' . $end_emp_token, $undecoded_excerpt);
|
| 296 |
}
|
| 380 |
return $whole;
|
| 381 |
}
|
| 382 |
|
| 383 |
+
/******
|
| 384 |
+
* This code originally written by Ben Boyter
|
| 385 |
+
* http://www.boyter.org/2013/04/building-a-search-result-extract-generator-in-php/
|
| 386 |
+
*/
|
| 387 |
+
|
| 388 |
+
// find the locations of each of the words
|
| 389 |
+
// Nothing exciting here. The array_unique is required
|
| 390 |
+
// unless you decide to make the words unique before passing in
|
| 391 |
+
function relevanssi_extract_locations($words, $fulltext) {
|
| 392 |
+
$locations = array();
|
| 393 |
+
foreach($words as $word) {
|
| 394 |
+
$wordlen = relevanssi_strlen($word);
|
| 395 |
+
$loc = relevanssi_stripos($fulltext, $word);
|
| 396 |
+
while($loc !== FALSE) {
|
| 397 |
+
$locations[] = $loc;
|
| 398 |
+
$loc = relevanssi_stripos($fulltext, $word, $loc + $wordlen);
|
| 399 |
+
}
|
| 400 |
+
}
|
| 401 |
+
$locations = array_unique($locations);
|
| 402 |
+
sort($locations);
|
| 403 |
+
|
| 404 |
+
return $locations;
|
| 405 |
+
}
|
| 406 |
+
|
| 407 |
+
function relevanssi_count_matches($words, $fulltext) {
|
| 408 |
+
$count = 0;
|
| 409 |
+
foreach( $words as $word ) {
|
| 410 |
+
if (get_option('relevanssi_fuzzy') == 'never') {
|
| 411 |
+
$pattern = '/([\s,\.:;]'.$word.'[\s,\.:;])/i';
|
| 412 |
+
if (preg_match($pattern, $fulltext, $matches, PREG_OFFSET_CAPTURE)) {
|
| 413 |
+
$count += count($matches) - 1;
|
| 414 |
+
}
|
| 415 |
+
}
|
| 416 |
+
else {
|
| 417 |
+
$pattern = '/([\s,\.:;]'.$word.')/i';
|
| 418 |
+
if (preg_match($pattern, $fulltext, $matches, PREG_OFFSET_CAPTURE)) {
|
| 419 |
+
$count += count($matches) - 1;
|
| 420 |
+
}
|
| 421 |
+
$pattern = '/('.$word.'[\s,\.:;])/i';
|
| 422 |
+
if (preg_match($pattern, $fulltext, $matches, PREG_OFFSET_CAPTURE)) {
|
| 423 |
+
$count += count($matches) - 1;
|
| 424 |
+
}
|
| 425 |
+
}
|
| 426 |
+
}
|
| 427 |
+
|
| 428 |
+
return $count;
|
| 429 |
+
}
|
| 430 |
+
|
| 431 |
+
// Work out which is the most relevant portion to display
|
| 432 |
+
// This is done by looping over each match and finding the smallest distance between two found
|
| 433 |
+
// strings. The idea being that the closer the terms are the better match the snippet would be.
|
| 434 |
+
// When checking for matches we only change the location if there is a better match.
|
| 435 |
+
// The only exception is where we have only two matches in which case we just take the
|
| 436 |
+
// first as will be equally distant.
|
| 437 |
+
function relevanssi_determine_snip_location($locations, $prevcount) {
|
| 438 |
+
// If we only have 1 match we dont actually do the for loop so set to the first
|
| 439 |
+
$startpos = $locations[0];
|
| 440 |
+
$loccount = count($locations);
|
| 441 |
+
$smallestdiff = PHP_INT_MAX;
|
| 442 |
+
|
| 443 |
+
// If we only have 2 skip as its probably equally relevant
|
| 444 |
+
if(count($locations) > 2) {
|
| 445 |
+
// skip the first as we check 1 behind
|
| 446 |
+
for($i=1; $i < $loccount; $i++) {
|
| 447 |
+
if($i == $loccount-1) { // at the end
|
| 448 |
+
$diff = $locations[$i] - $locations[$i-1];
|
| 449 |
+
}
|
| 450 |
+
else {
|
| 451 |
+
$diff = $locations[$i+1] - $locations[$i];
|
| 452 |
+
}
|
| 453 |
+
|
| 454 |
+
if($smallestdiff > $diff) {
|
| 455 |
+
$smallestdiff = $diff;
|
| 456 |
+
$startpos = $locations[$i];
|
| 457 |
+
}
|
| 458 |
+
}
|
| 459 |
+
}
|
| 460 |
+
|
| 461 |
+
$startpos = $startpos > $prevcount ? $startpos - $prevcount : 0;
|
| 462 |
+
return $startpos;
|
| 463 |
+
}
|
| 464 |
+
|
| 465 |
+
// 1/6 ratio on prevcount tends to work pretty well and puts the terms
|
| 466 |
+
// in the middle of the extract
|
| 467 |
+
function relevanssi_extract_relevant($words, $fulltext, $rellength=300, $prevcount=50) {
|
| 468 |
+
|
| 469 |
+
$textlength = mb_strlen($fulltext);
|
| 470 |
+
if($textlength <= $rellength) {
|
| 471 |
+
return $fulltext;
|
| 472 |
+
}
|
| 473 |
+
|
| 474 |
+
$locations = relevanssi_extract_locations($words, $fulltext);
|
| 475 |
+
$startpos = relevanssi_determine_snip_location($locations,$prevcount);
|
| 476 |
+
|
| 477 |
+
// if we are going to snip too much...
|
| 478 |
+
if($textlength-$startpos < $rellength) {
|
| 479 |
+
$startpos = $startpos - ($textlength-$startpos)/2;
|
| 480 |
+
}
|
| 481 |
+
|
| 482 |
+
$reltext = mb_substr($fulltext, $startpos, $rellength);
|
| 483 |
+
|
| 484 |
+
// check to ensure we dont snip the last word if thats the match
|
| 485 |
+
if( $startpos + $rellength < $textlength) {
|
| 486 |
+
$reltext = mb_substr($reltext, 0, mb_strrpos($reltext, " ")); // remove last word
|
| 487 |
+
}
|
| 488 |
+
|
| 489 |
+
$start = false;
|
| 490 |
+
if($startpos == 0) $start = true;
|
| 491 |
+
|
| 492 |
+
$besthits = count(relevanssi_extract_locations($words, $reltext));
|
| 493 |
+
|
| 494 |
+
return array($reltext, $besthits, $start);
|
| 495 |
+
}
|
| 496 |
+
|
| 497 |
?>
|
lib/indexing.php
CHANGED
|
@@ -313,7 +313,7 @@ function relevanssi_index_doc($indexpost, $remove_first = false, $custom_fields
|
|
| 313 |
$index_titles = true;
|
| 314 |
if (apply_filters('relevanssi_index_titles', $index_titles)) {
|
| 315 |
$filtered_title = apply_filters('relevanssi_post_title_before_tokenize', $post->post_title, $post);
|
| 316 |
-
$titles = relevanssi_tokenize(apply_filters('the_title', $filtered_title));
|
| 317 |
|
| 318 |
if (count($titles) > 0) {
|
| 319 |
foreach ($titles as $title => $count) {
|
|
@@ -361,6 +361,7 @@ function relevanssi_index_doc($indexpost, $remove_first = false, $custom_fields
|
|
| 361 |
remove_shortcode('product_categories'); // A problematic WooCommerce shortcode
|
| 362 |
remove_shortcode('recent_products'); // A problematic WooCommerce shortcode
|
| 363 |
remove_shortcode('php'); // PHP Code for Posts
|
|
|
|
| 364 |
|
| 365 |
$post_before_shortcode = $post;
|
| 366 |
$contents = do_shortcode($contents);
|
|
@@ -530,6 +531,7 @@ function relevanssi_update_child_posts($new_status, $old_status, $post) {
|
|
| 530 |
|| (in_array($post->post_type, array('attachment', 'revision')))) {
|
| 531 |
return;
|
| 532 |
}
|
|
|
|
| 533 |
$q = "SELECT * FROM $wpdb->posts WHERE post_parent=$post->ID AND post_type!='revision'";
|
| 534 |
$child_posts = $wpdb->get_results($q);
|
| 535 |
if ($child_posts) {
|
| 313 |
$index_titles = true;
|
| 314 |
if (apply_filters('relevanssi_index_titles', $index_titles)) {
|
| 315 |
$filtered_title = apply_filters('relevanssi_post_title_before_tokenize', $post->post_title, $post);
|
| 316 |
+
$titles = relevanssi_tokenize(apply_filters('the_title', $filtered_title, $post->ID));
|
| 317 |
|
| 318 |
if (count($titles) > 0) {
|
| 319 |
foreach ($titles as $title => $count) {
|
| 361 |
remove_shortcode('product_categories'); // A problematic WooCommerce shortcode
|
| 362 |
remove_shortcode('recent_products'); // A problematic WooCommerce shortcode
|
| 363 |
remove_shortcode('php'); // PHP Code for Posts
|
| 364 |
+
remove_shortcode('watupro'); // Watu PRO doesn't co-operate
|
| 365 |
|
| 366 |
$post_before_shortcode = $post;
|
| 367 |
$contents = do_shortcode($contents);
|
| 531 |
|| (in_array($post->post_type, array('attachment', 'revision')))) {
|
| 532 |
return;
|
| 533 |
}
|
| 534 |
+
|
| 535 |
$q = "SELECT * FROM $wpdb->posts WHERE post_parent=$post->ID AND post_type!='revision'";
|
| 536 |
$child_posts = $wpdb->get_results($q);
|
| 537 |
if ($child_posts) {
|
lib/init.php
CHANGED
|
@@ -38,7 +38,7 @@ function relevanssi_init() {
|
|
| 38 |
function relevanssi_warning() {
|
| 39 |
RELEVANSSI_PREMIUM ? $plugin = 'relevanssi-premium' : $plugin = 'relevanssi';
|
| 40 |
echo "<div id='relevanssi-warning' class='update-nag'><p><strong>"
|
| 41 |
-
. __('You do not have an index! Remember to build the index (click the "Build the index" button), otherwise searching won\'t work.')
|
| 42 |
. "</strong></p></div>";
|
| 43 |
}
|
| 44 |
if ( 'options-general.php' == $pagenow and isset( $_GET['page'] ) and plugin_basename($relevanssi_variables['file']) == $_GET['page'] ) {
|
|
@@ -54,8 +54,7 @@ function relevanssi_init() {
|
|
| 54 |
if (!function_exists('mb_internal_encoding')) {
|
| 55 |
function relevanssi_mb_warning() {
|
| 56 |
echo "<div id='relevanssi-warning' class='error'><p><strong>"
|
| 57 |
-
. "Multibyte string functions are not available. Relevanssi may not work well without them. "
|
| 58 |
-
. "Please install (or ask your host to install) the mbstring extension."
|
| 59 |
. "</strong></p></div>";
|
| 60 |
}
|
| 61 |
if ( 'options-general.php' == $pagenow and isset( $_GET['page'] ) and plugin_basename($relevanssi_variables['file']) == $_GET['page'] )
|
| 38 |
function relevanssi_warning() {
|
| 39 |
RELEVANSSI_PREMIUM ? $plugin = 'relevanssi-premium' : $plugin = 'relevanssi';
|
| 40 |
echo "<div id='relevanssi-warning' class='update-nag'><p><strong>"
|
| 41 |
+
. __('You do not have an index! Remember to build the index (click the "Build the index" button), otherwise searching won\'t work.', 'relevanssi')
|
| 42 |
. "</strong></p></div>";
|
| 43 |
}
|
| 44 |
if ( 'options-general.php' == $pagenow and isset( $_GET['page'] ) and plugin_basename($relevanssi_variables['file']) == $_GET['page'] ) {
|
| 54 |
if (!function_exists('mb_internal_encoding')) {
|
| 55 |
function relevanssi_mb_warning() {
|
| 56 |
echo "<div id='relevanssi-warning' class='error'><p><strong>"
|
| 57 |
+
. __("Multibyte string functions are not available. Relevanssi may not work well without them. Please install (or ask your host to install) the mbstring extension.", 'relevanssi')
|
|
|
|
| 58 |
. "</strong></p></div>";
|
| 59 |
}
|
| 60 |
if ( 'options-general.php' == $pagenow and isset( $_GET['page'] ) and plugin_basename($relevanssi_variables['file']) == $_GET['page'] )
|
lib/interface.php
CHANGED
|
@@ -108,7 +108,7 @@ function relevanssi_search_stats() {
|
|
| 108 |
relevanssi_query_log();
|
| 109 |
}
|
| 110 |
else {
|
| 111 |
-
echo "<p>Enable query logging to see stats here
|
| 112 |
}
|
| 113 |
|
| 114 |
echo "</div>";
|
|
@@ -123,7 +123,7 @@ function relevanssi_truncate_logs() {
|
|
| 123 |
$query = "TRUNCATE " . $relevanssi_variables['log_table'];
|
| 124 |
$wpdb->query($query);
|
| 125 |
|
| 126 |
-
echo "<div id='relevanssi-warning' class='updated fade'>Logs clear
|
| 127 |
}
|
| 128 |
|
| 129 |
function update_relevanssi_options() {
|
|
@@ -856,9 +856,9 @@ function relevanssi_options_form() {
|
|
| 856 |
|
| 857 |
<h3><?php _e('Quick tools', 'relevanssi') ?></h3>
|
| 858 |
<p>
|
| 859 |
-
<input type='submit' name='submit' value='<?php
|
| 860 |
-
<input type="submit" name="index" value="<?php
|
| 861 |
-
<input type="submit" name="index_extend" value="<?php
|
| 862 |
|
| 863 |
<?php
|
| 864 |
if (empty($index_post_types)) {
|
|
@@ -1175,7 +1175,7 @@ function relevanssi_options_form() {
|
|
| 1175 |
<br />
|
| 1176 |
<br />
|
| 1177 |
|
| 1178 |
-
<input type='submit' name='submit' value='<?php
|
| 1179 |
|
| 1180 |
<h3 id="indexing"><?php _e('Indexing options', 'relevanssi'); ?></h3>
|
| 1181 |
|
|
@@ -1321,9 +1321,9 @@ EOH;
|
|
| 1321 |
|
| 1322 |
<?php if (function_exists('relevanssi_form_index_taxonomies')) relevanssi_form_index_taxonomies($index_taxonomies, $index_terms); ?>
|
| 1323 |
|
| 1324 |
-
<input type='submit' name='index' value='<?php
|
| 1325 |
|
| 1326 |
-
<input type='submit' name='index_extend' value='<?php
|
| 1327 |
|
| 1328 |
<h3 id="synonyms"><?php _e("Synonyms", "relevanssi"); ?></h3>
|
| 1329 |
|
|
@@ -1333,7 +1333,7 @@ EOH;
|
|
| 1333 |
|
| 1334 |
<?php if (function_exists('relevanssi_form_index_synonyms')) relevanssi_form_index_synonyms($index_synonyms); ?>
|
| 1335 |
|
| 1336 |
-
<input type='submit' name='submit' value='<?php
|
| 1337 |
|
| 1338 |
<h3 id="stopwords"><?php _e("Stopwords", "relevanssi"); ?></h3>
|
| 1339 |
|
|
@@ -1357,7 +1357,7 @@ function relevanssi_show_stopwords() {
|
|
| 1357 |
_e("<p>Enter a word here to add it to the list of stopwords. The word will automatically be removed from the index, so re-indexing is not necessary. You can enter many words at the same time, separate words with commas.</p>", 'relevanssi');
|
| 1358 |
|
| 1359 |
?><label for="addstopword"><p><?php _e("Stopword(s) to add: ", 'relevanssi'); ?><textarea name="addstopword" id="addstopword" rows="2" cols="40"></textarea>
|
| 1360 |
-
<input type="submit" value="<?php
|
| 1361 |
<?php
|
| 1362 |
|
| 1363 |
_e("<p>Here's a list of stopwords in the database. Click a word to remove it from stopwords. Removing stopwords won't automatically return them to index, so you need to re-index all posts after removing stopwords to get those words back to index.", 'relevanssi');
|
|
@@ -1386,7 +1386,7 @@ function relevanssi_show_stopwords() {
|
|
| 1386 |
echo "</ul>";
|
| 1387 |
|
| 1388 |
?>
|
| 1389 |
-
<p><input type="submit" name="removeallstopwords" value="<?php
|
| 1390 |
<?php
|
| 1391 |
|
| 1392 |
$exportlist = htmlspecialchars(implode(", ", $exportlist));
|
| 108 |
relevanssi_query_log();
|
| 109 |
}
|
| 110 |
else {
|
| 111 |
+
echo "<p>" . __('Enable query logging to see stats here.', 'relevanssi') . "</p>";
|
| 112 |
}
|
| 113 |
|
| 114 |
echo "</div>";
|
| 123 |
$query = "TRUNCATE " . $relevanssi_variables['log_table'];
|
| 124 |
$wpdb->query($query);
|
| 125 |
|
| 126 |
+
echo "<div id='relevanssi-warning' class='updated fade'>" . __('Logs clear!', 'relevanssi') . "</div>";
|
| 127 |
}
|
| 128 |
|
| 129 |
function update_relevanssi_options() {
|
| 856 |
|
| 857 |
<h3><?php _e('Quick tools', 'relevanssi') ?></h3>
|
| 858 |
<p>
|
| 859 |
+
<input type='submit' name='submit' value='<?php esc_attr_e('Save options', 'relevanssi'); ?>' class='button-primary' />
|
| 860 |
+
<input type="submit" name="index" value="<?php esc_attr_e('Build the index', 'relevanssi'); ?>" class='button-primary' />
|
| 861 |
+
<input type="submit" name="index_extend" value="<?php esc_attr_e('Continue indexing', 'relevanssi'); ?>" class='button-secondary' />, <?php _e('add', 'relevanssi'); ?> <input type="text" size="4" name="relevanssi_index_limit" value="<?php echo $index_limit ?>" /> <?php _e('documents.', 'relevanssi'); ?></p>
|
| 862 |
|
| 863 |
<?php
|
| 864 |
if (empty($index_post_types)) {
|
| 1175 |
<br />
|
| 1176 |
<br />
|
| 1177 |
|
| 1178 |
+
<input type='submit' name='submit' value='<?php esc_attr_e('Save the options', 'relevanssi'); ?>' class='button button-primary' />
|
| 1179 |
|
| 1180 |
<h3 id="indexing"><?php _e('Indexing options', 'relevanssi'); ?></h3>
|
| 1181 |
|
| 1321 |
|
| 1322 |
<?php if (function_exists('relevanssi_form_index_taxonomies')) relevanssi_form_index_taxonomies($index_taxonomies, $index_terms); ?>
|
| 1323 |
|
| 1324 |
+
<input type='submit' name='index' value='<?php esc_attr_e("Save indexing options, erase index and rebuild the index", 'relevanssi'); ?>' class='button button-primary' />
|
| 1325 |
|
| 1326 |
+
<input type='submit' name='index_extend' value='<?php esc_attr_e("Continue indexing", 'relevanssi'); ?>' class='button' />
|
| 1327 |
|
| 1328 |
<h3 id="synonyms"><?php _e("Synonyms", "relevanssi"); ?></h3>
|
| 1329 |
|
| 1333 |
|
| 1334 |
<?php if (function_exists('relevanssi_form_index_synonyms')) relevanssi_form_index_synonyms($index_synonyms); ?>
|
| 1335 |
|
| 1336 |
+
<input type='submit' name='submit' value='<?php esc_attr_e('Save the options', 'relevanssi'); ?>' class='button' />
|
| 1337 |
|
| 1338 |
<h3 id="stopwords"><?php _e("Stopwords", "relevanssi"); ?></h3>
|
| 1339 |
|
| 1357 |
_e("<p>Enter a word here to add it to the list of stopwords. The word will automatically be removed from the index, so re-indexing is not necessary. You can enter many words at the same time, separate words with commas.</p>", 'relevanssi');
|
| 1358 |
|
| 1359 |
?><label for="addstopword"><p><?php _e("Stopword(s) to add: ", 'relevanssi'); ?><textarea name="addstopword" id="addstopword" rows="2" cols="40"></textarea>
|
| 1360 |
+
<input type="submit" value="<?php esc_attr_e("Add", 'relevanssi'); ?>" class='button' /></p></label>
|
| 1361 |
<?php
|
| 1362 |
|
| 1363 |
_e("<p>Here's a list of stopwords in the database. Click a word to remove it from stopwords. Removing stopwords won't automatically return them to index, so you need to re-index all posts after removing stopwords to get those words back to index.", 'relevanssi');
|
| 1386 |
echo "</ul>";
|
| 1387 |
|
| 1388 |
?>
|
| 1389 |
+
<p><input type="submit" name="removeallstopwords" value="<?php esc_attr_e('Remove all stopwords', 'relevanssi'); ?>" class='button' /></p>
|
| 1390 |
<?php
|
| 1391 |
|
| 1392 |
$exportlist = htmlspecialchars(implode(", ", $exportlist));
|
lib/search.php
CHANGED
|
@@ -376,6 +376,8 @@ function relevanssi_search($args) {
|
|
| 376 |
$comment_matches = array();
|
| 377 |
$link_matches = array();
|
| 378 |
$body_matches = array();
|
|
|
|
|
|
|
| 379 |
$scores = array();
|
| 380 |
$term_hits = array();
|
| 381 |
|
|
@@ -627,6 +629,8 @@ function relevanssi_search($args) {
|
|
| 627 |
isset($title_matches[$match->doc]) ? $title_matches[$match->doc] += $match->title : $title_matches[$match->doc] = $match->title;
|
| 628 |
isset($link_matches[$match->doc]) ? $link_matches[$match->doc] += $match->link : $link_matches[$match->doc] = $match->link;
|
| 629 |
isset($tag_matches[$match->doc]) ? $tag_matches[$match->doc] += $match->tag : $tag_matches[$match->doc] = $match->tag;
|
|
|
|
|
|
|
| 630 |
isset($comment_matches[$match->doc]) ? $comment_matches[$match->doc] += $match->comment : $comment_matches[$match->doc] = $match->comment;
|
| 631 |
|
| 632 |
isset($relevanssi_post_types[$match->doc]) ? $type = $relevanssi_post_types[$match->doc] : $type = null;
|
|
@@ -693,9 +697,23 @@ function relevanssi_search($args) {
|
|
| 693 |
// doc didn't match all terms, so it's discarded
|
| 694 |
continue;
|
| 695 |
}
|
| 696 |
-
|
| 697 |
-
|
| 698 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 699 |
$i++;
|
| 700 |
}
|
| 701 |
}
|
|
@@ -727,7 +745,8 @@ function relevanssi_search($args) {
|
|
| 727 |
relevanssi_object_sort($hits, $orderby, $order);
|
| 728 |
|
| 729 |
$return = array('hits' => $hits, 'body_matches' => $body_matches, 'title_matches' => $title_matches,
|
| 730 |
-
'tag_matches' => $tag_matches, '
|
|
|
|
| 731 |
'term_hits' => $term_hits, 'query' => $q, 'link_matches' => $link_matches);
|
| 732 |
|
| 733 |
return $return;
|
|
@@ -978,8 +997,8 @@ function relevanssi_do_query(&$query) {
|
|
| 978 |
|
| 979 |
$expost = get_option("relevanssi_exclude_posts");
|
| 980 |
|
| 981 |
-
|
| 982 |
-
|
| 983 |
$excat = null;
|
| 984 |
$extag = null;
|
| 985 |
$expost = null;
|
|
@@ -994,6 +1013,16 @@ function relevanssi_do_query(&$query) {
|
|
| 994 |
|
| 995 |
isset($query->query_vars['orderby']) ? $orderby = $query->query_vars['orderby'] : $orderby = null;
|
| 996 |
isset($query->query_vars['order']) ? $order = $query->query_vars['order'] : $order = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 997 |
|
| 998 |
// Add synonyms
|
| 999 |
// This is done here so the new terms will get highlighting
|
|
@@ -1017,7 +1046,8 @@ function relevanssi_do_query(&$query) {
|
|
| 1017 |
'search_blogs' => $search_blogs,
|
| 1018 |
'author' => $author,
|
| 1019 |
'orderby' => $orderby,
|
| 1020 |
-
'order' => $order
|
|
|
|
| 1021 |
|
| 1022 |
$return = relevanssi_search($search_params);
|
| 1023 |
}
|
|
@@ -1100,16 +1130,23 @@ function relevanssi_do_query(&$query) {
|
|
| 1100 |
}
|
| 1101 |
// OdditY end <-
|
| 1102 |
|
| 1103 |
-
if ('on' == $make_excerpts) {
|
| 1104 |
$post->original_excerpt = $post->post_excerpt;
|
| 1105 |
$post->post_excerpt = relevanssi_do_excerpt($post, $q);
|
| 1106 |
}
|
| 1107 |
|
| 1108 |
-
if ('on' == get_option('relevanssi_show_matches')) {
|
| 1109 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1110 |
}
|
| 1111 |
|
| 1112 |
-
if (isset($return['scores'][$post->ID])) $post->relevance_score = round($return['scores'][$post->ID], 2);
|
| 1113 |
|
| 1114 |
$posts[] = $post;
|
| 1115 |
}
|
| 376 |
$comment_matches = array();
|
| 377 |
$link_matches = array();
|
| 378 |
$body_matches = array();
|
| 379 |
+
$category_matches = array();
|
| 380 |
+
$taxonomy_matches = array();
|
| 381 |
$scores = array();
|
| 382 |
$term_hits = array();
|
| 383 |
|
| 629 |
isset($title_matches[$match->doc]) ? $title_matches[$match->doc] += $match->title : $title_matches[$match->doc] = $match->title;
|
| 630 |
isset($link_matches[$match->doc]) ? $link_matches[$match->doc] += $match->link : $link_matches[$match->doc] = $match->link;
|
| 631 |
isset($tag_matches[$match->doc]) ? $tag_matches[$match->doc] += $match->tag : $tag_matches[$match->doc] = $match->tag;
|
| 632 |
+
isset($category_matches[$match->doc]) ? $category_matches[$match->doc] += $match->category : $category_matches[$match->doc] = $match->category;
|
| 633 |
+
isset($taxonomy_matches[$match->doc]) ? $taxonomy_matches[$match->doc] += $match->taxonomy : $taxonomy_matches[$match->doc] = $match->taxonomy;
|
| 634 |
isset($comment_matches[$match->doc]) ? $comment_matches[$match->doc] += $match->comment : $comment_matches[$match->doc] = $match->comment;
|
| 635 |
|
| 636 |
isset($relevanssi_post_types[$match->doc]) ? $type = $relevanssi_post_types[$match->doc] : $type = null;
|
| 697 |
// doc didn't match all terms, so it's discarded
|
| 698 |
continue;
|
| 699 |
}
|
| 700 |
+
|
| 701 |
+
if (!empty($fields)) {
|
| 702 |
+
if ($fields == 'ids') {
|
| 703 |
+
$hits[intval($i)] = $doc;
|
| 704 |
+
}
|
| 705 |
+
if ($fields == 'id=>parent') {
|
| 706 |
+
$object = new StdClass();
|
| 707 |
+
$object->ID = $doc;
|
| 708 |
+
$object->post_parent = wp_get_post_parent_id($doc);
|
| 709 |
+
|
| 710 |
+
$hits[intval($i)] = $object;
|
| 711 |
+
}
|
| 712 |
+
}
|
| 713 |
+
else {
|
| 714 |
+
$hits[intval($i)] = relevanssi_get_post($doc);
|
| 715 |
+
$hits[intval($i)]->relevance_score = round($weight, 2);
|
| 716 |
+
}
|
| 717 |
$i++;
|
| 718 |
}
|
| 719 |
}
|
| 745 |
relevanssi_object_sort($hits, $orderby, $order);
|
| 746 |
|
| 747 |
$return = array('hits' => $hits, 'body_matches' => $body_matches, 'title_matches' => $title_matches,
|
| 748 |
+
'tag_matches' => $tag_matches, 'category_matches' => $category_matches, 'taxonomy_matches' => $taxonomy_matches,
|
| 749 |
+
'comment_matches' => $comment_matches, 'scores' => $scores,
|
| 750 |
'term_hits' => $term_hits, 'query' => $q, 'link_matches' => $link_matches);
|
| 751 |
|
| 752 |
return $return;
|
| 997 |
|
| 998 |
$expost = get_option("relevanssi_exclude_posts");
|
| 999 |
|
| 1000 |
+
// In admin (and when not AJAX), search everything
|
| 1001 |
+
if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) ) {
|
| 1002 |
$excat = null;
|
| 1003 |
$extag = null;
|
| 1004 |
$expost = null;
|
| 1013 |
|
| 1014 |
isset($query->query_vars['orderby']) ? $orderby = $query->query_vars['orderby'] : $orderby = null;
|
| 1015 |
isset($query->query_vars['order']) ? $order = $query->query_vars['order'] : $order = null;
|
| 1016 |
+
|
| 1017 |
+
$fields = "";
|
| 1018 |
+
if (!empty($query->query_vars['fields'])) {
|
| 1019 |
+
if ($query->query_vars['fields'] == 'ids') {
|
| 1020 |
+
$fields = 'ids';
|
| 1021 |
+
}
|
| 1022 |
+
if ($query->query_vars['fields'] == 'id=>parent') {
|
| 1023 |
+
$fields = 'id=>parent';
|
| 1024 |
+
}
|
| 1025 |
+
}
|
| 1026 |
|
| 1027 |
// Add synonyms
|
| 1028 |
// This is done here so the new terms will get highlighting
|
| 1046 |
'search_blogs' => $search_blogs,
|
| 1047 |
'author' => $author,
|
| 1048 |
'orderby' => $orderby,
|
| 1049 |
+
'order' => $order,
|
| 1050 |
+
'fields' => $fields);
|
| 1051 |
|
| 1052 |
$return = relevanssi_search($search_params);
|
| 1053 |
}
|
| 1130 |
}
|
| 1131 |
// OdditY end <-
|
| 1132 |
|
| 1133 |
+
if ('on' == $make_excerpts && empty($fields)) {
|
| 1134 |
$post->original_excerpt = $post->post_excerpt;
|
| 1135 |
$post->post_excerpt = relevanssi_do_excerpt($post, $q);
|
| 1136 |
}
|
| 1137 |
|
| 1138 |
+
if ('on' == get_option('relevanssi_show_matches') && empty($fields)) {
|
| 1139 |
+
$post_id = $post->ID;
|
| 1140 |
+
if ($post->post_type == 'user') {
|
| 1141 |
+
$post_id = "u_" . $post->user_id;
|
| 1142 |
+
}
|
| 1143 |
+
else if (isset($post->term_id)) {
|
| 1144 |
+
$post_id = '**' . $post->post_type . '**' . $post->term_id;
|
| 1145 |
+
}
|
| 1146 |
+
$post->post_excerpt .= relevanssi_show_matches($return, $post_id);
|
| 1147 |
}
|
| 1148 |
|
| 1149 |
+
if (empty($fields) && isset($return['scores'][$post->ID])) $post->relevance_score = round($return['scores'][$post->ID], 2);
|
| 1150 |
|
| 1151 |
$posts[] = $post;
|
| 1152 |
}
|
lib/shortcodes.php
CHANGED
|
@@ -29,7 +29,7 @@ function relevanssi_shortcode($atts, $content, $name) {
|
|
| 29 |
|
| 30 |
function relevanssi_noindex_shortcode($atts, $content) {
|
| 31 |
// When in general use, make the shortcode disappear.
|
| 32 |
-
return $content;
|
| 33 |
}
|
| 34 |
|
| 35 |
function relevanssi_noindex_shortcode_indexing($atts, $content) {
|
| 29 |
|
| 30 |
function relevanssi_noindex_shortcode($atts, $content) {
|
| 31 |
// When in general use, make the shortcode disappear.
|
| 32 |
+
return do_shortcode($content);
|
| 33 |
}
|
| 34 |
|
| 35 |
function relevanssi_noindex_shortcode_indexing($atts, $content) {
|
readme.txt
CHANGED
|
@@ -3,8 +3,8 @@ Contributors: msaari
|
|
| 3 |
Donate link: http://www.relevanssi.com/buy-premium/
|
| 4 |
Tags: search, relevance, better search
|
| 5 |
Requires at least: 3.3
|
| 6 |
-
Tested up to: 4.
|
| 7 |
-
Stable tag: 3.
|
| 8 |
License: GPLv2 or later
|
| 9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
| 10 |
|
|
@@ -386,6 +386,19 @@ removing those words helps to make the index smaller and searching faster.
|
|
| 386 |
|
| 387 |
== Changelog ==
|
| 388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 389 |
= 3.4.2 =
|
| 390 |
* Empty lines on synonym settings caused problems. Fixed that.
|
| 391 |
* In WordPress 4.2 installations, emoji in will be handled better. Emoji in posts may cause problems with WordPress versions below 4.2, so please update!
|
|
@@ -1078,6 +1091,9 @@ removing those words helps to make the index smaller and searching faster.
|
|
| 1078 |
|
| 1079 |
== Upgrade notice ==
|
| 1080 |
|
|
|
|
|
|
|
|
|
|
| 1081 |
= 3.4.2 =
|
| 1082 |
* Better emoji support in WP 4.2, fixed issues with synonyms.
|
| 1083 |
|
| 3 |
Donate link: http://www.relevanssi.com/buy-premium/
|
| 4 |
Tags: search, relevance, better search
|
| 5 |
Requires at least: 3.3
|
| 6 |
+
Tested up to: 4.4
|
| 7 |
+
Stable tag: 3.5
|
| 8 |
License: GPLv2 or later
|
| 9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
| 10 |
|
| 386 |
|
| 387 |
== Changelog ==
|
| 388 |
|
| 389 |
+
= 3.5 =
|
| 390 |
+
* Tokenizer was using `strlen()` and not `mb_strlen()`, so word lengths were not calculated properly. If your site uses non-ASCII alphabet, rebuilding the index is a good idea.
|
| 391 |
+
* Small improvement to WPML multilanguage filtering.
|
| 392 |
+
* `relevanssi_the_title()` got a new parameter: if you don't want to echo the title, you can use it like `relevanssi_the_title(false)` to make it return the title.
|
| 393 |
+
* Relevanssi had `the_title` filter hook calls that were missing the second parameter; that's now fixed.
|
| 394 |
+
* The excerpt-building algorithm is completely rewritten based on work by Ben Boyter (http://www.boyter.org/).
|
| 395 |
+
* The `[watupro]` shortcode didn't work with Relevanssi, so Relevanssi will now bypass it.
|
| 396 |
+
* The plugin i18n features have been improved slightly.
|
| 397 |
+
* New filter: `relevanssi_didyoumean_suggestion` lets you modify the Did you mean? suggestion before it's displayed.
|
| 398 |
+
* `relevanssi_didyoumean()` has a new parameter: you can now choose whether the result is echoed out (the default value) or just returned.
|
| 399 |
+
* In the search results breakdown, you can now use %categories% and %taxonomies% to show the number of matches in categories and taxonomies other than tags and cats, respectively.
|
| 400 |
+
* Relevanssi supports `fields` parameter (both `ids` and `id=>parent`) to return only post IDs or post IDs and post parents.
|
| 401 |
+
|
| 402 |
= 3.4.2 =
|
| 403 |
* Empty lines on synonym settings caused problems. Fixed that.
|
| 404 |
* In WordPress 4.2 installations, emoji in will be handled better. Emoji in posts may cause problems with WordPress versions below 4.2, so please update!
|
| 1091 |
|
| 1092 |
== Upgrade notice ==
|
| 1093 |
|
| 1094 |
+
= 3.5 =
|
| 1095 |
+
* Improved excerpt-building, several bug fixes, couple of small updates.
|
| 1096 |
+
|
| 1097 |
= 3.4.2 =
|
| 1098 |
* Better emoji support in WP 4.2, fixed issues with synonyms.
|
| 1099 |
|
relevanssi.php
CHANGED
|
@@ -3,10 +3,9 @@
|
|
| 3 |
Plugin Name: Relevanssi
|
| 4 |
Plugin URI: http://www.relevanssi.com/
|
| 5 |
Description: This plugin replaces WordPress search with a relevance-sorting search.
|
| 6 |
-
Version: 3.
|
| 7 |
Author: Mikko Saari
|
| 8 |
Author URI: http://www.mikkosaari.fi/
|
| 9 |
-
Text Domain: relevanssi
|
| 10 |
*/
|
| 11 |
|
| 12 |
/* Copyright 2015 Mikko Saari (email: mikko@mikkosaari.fi)
|
|
@@ -59,7 +58,7 @@ require_once('lib/excerpts-highlights.php');
|
|
| 59 |
require_once('lib/shortcodes.php');
|
| 60 |
require_once('lib/common.php');
|
| 61 |
|
| 62 |
-
function relevanssi_didyoumean($query, $pre, $post, $n = 5) {
|
| 63 |
global $wpdb, $relevanssi_variables, $wp_query;
|
| 64 |
|
| 65 |
$total_results = $wp_query->found_posts;
|
|
@@ -88,14 +87,14 @@ function relevanssi_didyoumean($query, $pre, $post, $n = 5) {
|
|
| 88 |
}
|
| 89 |
|
| 90 |
if ($distance > 0) {
|
| 91 |
-
|
| 92 |
$url = get_bloginfo('url');
|
| 93 |
$url = esc_attr(add_query_arg(array(
|
| 94 |
's' => urlencode($closest)
|
| 95 |
|
| 96 |
), $url ));
|
| 97 |
$url = apply_filters('relevanssi_didyoumean_url', $url);
|
| 98 |
-
|
|
|
|
| 99 |
}
|
| 100 |
|
| 101 |
|
|
@@ -251,7 +250,7 @@ function _relevanssi_install() {
|
|
| 251 |
add_option('relevanssi_highlight_comments', 'off');
|
| 252 |
add_option('relevanssi_index_comments', 'none'); //added by OdditY
|
| 253 |
add_option('relevanssi_show_matches', '');
|
| 254 |
-
add_option('relevanssi_show_matches_text', '(Search hits: %body% in body, %title% in title, %tags% in tags, %comments% in comments. Score: %score%)');
|
| 255 |
add_option('relevanssi_fuzzy', 'sometimes');
|
| 256 |
add_option('relevanssi_indexed', '');
|
| 257 |
add_option('relevanssi_expand_shortcodes', 'on');
|
| 3 |
Plugin Name: Relevanssi
|
| 4 |
Plugin URI: http://www.relevanssi.com/
|
| 5 |
Description: This plugin replaces WordPress search with a relevance-sorting search.
|
| 6 |
+
Version: 3.5
|
| 7 |
Author: Mikko Saari
|
| 8 |
Author URI: http://www.mikkosaari.fi/
|
|
|
|
| 9 |
*/
|
| 10 |
|
| 11 |
/* Copyright 2015 Mikko Saari (email: mikko@mikkosaari.fi)
|
| 58 |
require_once('lib/shortcodes.php');
|
| 59 |
require_once('lib/common.php');
|
| 60 |
|
| 61 |
+
function relevanssi_didyoumean($query, $pre, $post, $n = 5, $echo = true) {
|
| 62 |
global $wpdb, $relevanssi_variables, $wp_query;
|
| 63 |
|
| 64 |
$total_results = $wp_query->found_posts;
|
| 87 |
}
|
| 88 |
|
| 89 |
if ($distance > 0) {
|
|
|
|
| 90 |
$url = get_bloginfo('url');
|
| 91 |
$url = esc_attr(add_query_arg(array(
|
| 92 |
's' => urlencode($closest)
|
| 93 |
|
| 94 |
), $url ));
|
| 95 |
$url = apply_filters('relevanssi_didyoumean_url', $url);
|
| 96 |
+
$result = apply_filters('relevanssi_didyoumean_suggestion', "$pre<a href='$url'>$suggestion</a>$post");
|
| 97 |
+
if ($echo) echo $result;
|
| 98 |
}
|
| 99 |
|
| 100 |
|
| 250 |
add_option('relevanssi_highlight_comments', 'off');
|
| 251 |
add_option('relevanssi_index_comments', 'none'); //added by OdditY
|
| 252 |
add_option('relevanssi_show_matches', '');
|
| 253 |
+
add_option('relevanssi_show_matches_text', '(Search hits: %body% in body, %title% in title, %category% in categories, %tags% in tags, %taxonomy% in other taxonomies, %comments% in comments. Score: %score%)');
|
| 254 |
add_option('relevanssi_fuzzy', 'sometimes');
|
| 255 |
add_option('relevanssi_indexed', '');
|
| 256 |
add_option('relevanssi_expand_shortcodes', 'on');
|
