Version Description
- Fixed an error in the Did you mean function.
- Fixed an error if the search term was not found in content.
- Fixed an error when building excerpts from posts shorter than the excerpt length.
- Blocked the
[starpro]shortcode that was causing problems with Relevanssi. - New filter:
relevanssi_remove_stopwords_in_titlesallows you to include stopwords in titles. - Added support for
term_tax_idin thefieldsparameter in tax_queries. - Excerpt-building failed if multibyte string operations were missing. It should work now.
Download this release
Release Info
| Developer | msaari |
| Plugin | |
| Version | 3.5.1 |
| Comparing to | |
| See all releases | |
Code changes from version 3.5 to 3.5.1
- lib/excerpts-highlights.php +23 -6
- lib/indexing.php +2 -1
- lib/search.php +36 -7
- readme.txt +13 -1
- relevanssi.php +4 -4
lib/excerpts-highlights.php
CHANGED
|
@@ -392,7 +392,7 @@ 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);
|
|
@@ -435,6 +435,8 @@ function relevanssi_count_matches($words, $fulltext) {
|
|
| 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);
|
|
@@ -466,9 +468,14 @@ function relevanssi_determine_snip_location($locations, $prevcount) {
|
|
| 466 |
// in the middle of the extract
|
| 467 |
function relevanssi_extract_relevant($words, $fulltext, $rellength=300, $prevcount=50) {
|
| 468 |
|
| 469 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 470 |
if($textlength <= $rellength) {
|
| 471 |
-
return $fulltext;
|
| 472 |
}
|
| 473 |
|
| 474 |
$locations = relevanssi_extract_locations($words, $fulltext);
|
|
@@ -479,11 +486,21 @@ function relevanssi_extract_relevant($words, $fulltext, $rellength=300, $prevcou
|
|
| 479 |
$startpos = $startpos - ($textlength-$startpos)/2;
|
| 480 |
}
|
| 481 |
|
| 482 |
-
|
| 483 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 484 |
// check to ensure we dont snip the last word if thats the match
|
| 485 |
if( $startpos + $rellength < $textlength) {
|
| 486 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 487 |
}
|
| 488 |
|
| 489 |
$start = false;
|
| 392 |
$locations = array();
|
| 393 |
foreach($words as $word) {
|
| 394 |
$wordlen = relevanssi_strlen($word);
|
| 395 |
+
$loc = relevanssi_stripos($fulltext, $word, 0);
|
| 396 |
while($loc !== FALSE) {
|
| 397 |
$locations[] = $loc;
|
| 398 |
$loc = relevanssi_stripos($fulltext, $word, $loc + $wordlen);
|
| 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 (!is_array($locations)) return 0;
|
| 439 |
+
|
| 440 |
// If we only have 1 match we dont actually do the for loop so set to the first
|
| 441 |
$startpos = $locations[0];
|
| 442 |
$loccount = count($locations);
|
| 468 |
// in the middle of the extract
|
| 469 |
function relevanssi_extract_relevant($words, $fulltext, $rellength=300, $prevcount=50) {
|
| 470 |
|
| 471 |
+
if (function_exists('mb_strlen')) {
|
| 472 |
+
$textlength = mb_strlen($fulltext);
|
| 473 |
+
}
|
| 474 |
+
else {
|
| 475 |
+
$textlength = strlen($fulltext);
|
| 476 |
+
}
|
| 477 |
if($textlength <= $rellength) {
|
| 478 |
+
return array($fulltext, 1, 0);
|
| 479 |
}
|
| 480 |
|
| 481 |
$locations = relevanssi_extract_locations($words, $fulltext);
|
| 486 |
$startpos = $startpos - ($textlength-$startpos)/2;
|
| 487 |
}
|
| 488 |
|
| 489 |
+
if (function_exists('mb_substr')) {
|
| 490 |
+
$reltext = mb_substr($fulltext, $startpos, $rellength);
|
| 491 |
+
}
|
| 492 |
+
else {
|
| 493 |
+
$reltext = substr($fulltext, $startpos, $rellength);
|
| 494 |
+
}
|
| 495 |
+
|
| 496 |
// check to ensure we dont snip the last word if thats the match
|
| 497 |
if( $startpos + $rellength < $textlength) {
|
| 498 |
+
if (function_exists('mb_substr') && function_exists('mb_strrpos')) {
|
| 499 |
+
$reltext = mb_substr($reltext, 0, mb_strrpos($reltext, " ")); // remove last word
|
| 500 |
+
}
|
| 501 |
+
else {
|
| 502 |
+
$reltext = substr($reltext, 0, strrpos($reltext, " ")); // remove last word
|
| 503 |
+
}
|
| 504 |
}
|
| 505 |
|
| 506 |
$start = false;
|
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, $post->ID));
|
| 317 |
|
| 318 |
if (count($titles) > 0) {
|
| 319 |
foreach ($titles as $title => $count) {
|
|
@@ -362,6 +362,7 @@ function relevanssi_index_doc($indexpost, $remove_first = false, $custom_fields
|
|
| 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);
|
| 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), apply_filters('relevanssi_remove_stopwords_in_titles', true));
|
| 317 |
|
| 318 |
if (count($titles) > 0) {
|
| 319 |
foreach ($titles as $title => $count) {
|
| 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 |
+
remove_shortcode('starbox'); // Starbox shortcode breaks Relevanssi
|
| 366 |
|
| 367 |
$post_before_shortcode = $post;
|
| 368 |
$contents = do_shortcode($contents);
|
lib/search.php
CHANGED
|
@@ -65,6 +65,7 @@ function relevanssi_search($args) {
|
|
| 65 |
|
| 66 |
if (is_array($tax_query)) {
|
| 67 |
foreach ($tax_query as $row) {
|
|
|
|
| 68 |
if ($row['field'] == 'slug') {
|
| 69 |
$slug = $row['terms'];
|
| 70 |
$numeric_slugs = array();
|
|
@@ -130,12 +131,36 @@ function relevanssi_search($args) {
|
|
| 130 |
$term_tax_id = $id_term_tax_id;
|
| 131 |
}
|
| 132 |
}
|
| 133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
if (!isset($row['include_children']) || $row['include_children'] == true) {
|
| 135 |
-
if (
|
| 136 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
}
|
| 138 |
foreach ($term_id as $t_id) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
$kids = get_term_children($t_id, $row['taxonomy']);
|
| 140 |
foreach ($kids as $kid) {
|
| 141 |
$term = get_term_by('id', $kid, $row['taxonomy']);
|
|
@@ -328,7 +353,7 @@ function relevanssi_search($args) {
|
|
| 328 |
$query_restrictions .= $postex;
|
| 329 |
}
|
| 330 |
|
| 331 |
-
$remove_stopwords = true;
|
| 332 |
if (function_exists('wp_encode_emoji')) $q = wp_encode_emoji($q);
|
| 333 |
$phrases = relevanssi_recognize_phrases($q);
|
| 334 |
|
|
@@ -356,10 +381,10 @@ function relevanssi_search($args) {
|
|
| 356 |
|
| 357 |
if ($negative_terms) {
|
| 358 |
$terms = array_diff($terms, $negative_terms);
|
| 359 |
-
if (count($terms) < 1) {
|
| 360 |
return $hits;
|
| 361 |
}
|
| 362 |
-
}
|
| 363 |
|
| 364 |
// Go get the count from the options table, but keep running the full query if it's not available
|
| 365 |
$D = get_option('relevanssi_doc_count');
|
|
@@ -478,6 +503,11 @@ function relevanssi_search($args) {
|
|
| 478 |
else {
|
| 479 |
$o_term_cond = " relevanssi.term = '#term#' ";
|
| 480 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 481 |
|
| 482 |
$post_type_weights = get_option('relevanssi_post_type_weights');
|
| 483 |
if (function_exists('relevanssi_get_recency_bonus')) {
|
|
@@ -499,7 +529,6 @@ function relevanssi_search($args) {
|
|
| 499 |
do {
|
| 500 |
foreach ($terms as $term) {
|
| 501 |
$term = trim($term); // numeric search terms will start with a space
|
| 502 |
-
if (strlen($term) < $min_length) continue;
|
| 503 |
$term = esc_sql($term);
|
| 504 |
|
| 505 |
if (strpos($o_term_cond, 'LIKE') !== false) {
|
| 65 |
|
| 66 |
if (is_array($tax_query)) {
|
| 67 |
foreach ($tax_query as $row) {
|
| 68 |
+
$using_term_tax_id = false;
|
| 69 |
if ($row['field'] == 'slug') {
|
| 70 |
$slug = $row['terms'];
|
| 71 |
$numeric_slugs = array();
|
| 131 |
$term_tax_id = $id_term_tax_id;
|
| 132 |
}
|
| 133 |
}
|
| 134 |
+
if ($row['field'] == 'term_tax_id') {
|
| 135 |
+
$using_term_tax_id = true;
|
| 136 |
+
$id = $row['terms'];
|
| 137 |
+
$term_tax_id = $id;
|
| 138 |
+
if (is_array($id)) {
|
| 139 |
+
$numeric_values = array();
|
| 140 |
+
foreach ($id as $t_id) {
|
| 141 |
+
if (is_numeric($t_id)) $numeric_values[] = $t_id;
|
| 142 |
+
}
|
| 143 |
+
$term_tax_id = implode(',', $numeric_values);
|
| 144 |
+
}
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
if (!isset($row['include_children']) || $row['include_children'] == true) {
|
| 148 |
+
if (!$using_term_tax_id) {
|
| 149 |
+
if (!is_array($term_id)) {
|
| 150 |
+
$term_id = array($term_id);
|
| 151 |
+
}
|
| 152 |
+
}
|
| 153 |
+
else {
|
| 154 |
+
if (!is_array($term_tax_id)) {
|
| 155 |
+
$term_tax_id = array($term_tax_id);
|
| 156 |
+
$term_id = $term_tax_id;
|
| 157 |
+
}
|
| 158 |
}
|
| 159 |
foreach ($term_id as $t_id) {
|
| 160 |
+
if ($using_term_tax_id) {
|
| 161 |
+
$t_term = get_term_by('term_taxonomy_id', $t_id, $row['taxonomy']);
|
| 162 |
+
$t_id = $t_term->ID;
|
| 163 |
+
}
|
| 164 |
$kids = get_term_children($t_id, $row['taxonomy']);
|
| 165 |
foreach ($kids as $kid) {
|
| 166 |
$term = get_term_by('id', $kid, $row['taxonomy']);
|
| 353 |
$query_restrictions .= $postex;
|
| 354 |
}
|
| 355 |
|
| 356 |
+
$remove_stopwords = apply_filters('relevanssi_remove_stopwords_in_titles', true);
|
| 357 |
if (function_exists('wp_encode_emoji')) $q = wp_encode_emoji($q);
|
| 358 |
$phrases = relevanssi_recognize_phrases($q);
|
| 359 |
|
| 381 |
|
| 382 |
if ($negative_terms) {
|
| 383 |
$terms = array_diff($terms, $negative_terms);
|
| 384 |
+
/* if (count($terms) < 1) {
|
| 385 |
return $hits;
|
| 386 |
}
|
| 387 |
+
*/ }
|
| 388 |
|
| 389 |
// Go get the count from the options table, but keep running the full query if it's not available
|
| 390 |
$D = get_option('relevanssi_doc_count');
|
| 503 |
else {
|
| 504 |
$o_term_cond = " relevanssi.term = '#term#' ";
|
| 505 |
}
|
| 506 |
+
|
| 507 |
+
if (count($terms) < 1) {
|
| 508 |
+
$o_term_cond = " relevanssi.term = relevanssi.term ";
|
| 509 |
+
$terms[] = "term";
|
| 510 |
+
}
|
| 511 |
|
| 512 |
$post_type_weights = get_option('relevanssi_post_type_weights');
|
| 513 |
if (function_exists('relevanssi_get_recency_bonus')) {
|
| 529 |
do {
|
| 530 |
foreach ($terms as $term) {
|
| 531 |
$term = trim($term); // numeric search terms will start with a space
|
|
|
|
| 532 |
$term = esc_sql($term);
|
| 533 |
|
| 534 |
if (strpos($o_term_cond, 'LIKE') !== false) {
|
readme.txt
CHANGED
|
@@ -4,7 +4,7 @@ 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,6 +386,15 @@ removing those words helps to make the index smaller and searching faster.
|
|
| 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.
|
|
@@ -1091,6 +1100,9 @@ removing those words helps to make the index smaller and searching faster.
|
|
| 1091 |
|
| 1092 |
== Upgrade notice ==
|
| 1093 |
|
|
|
|
|
|
|
|
|
|
| 1094 |
= 3.5 =
|
| 1095 |
* Improved excerpt-building, several bug fixes, couple of small updates.
|
| 1096 |
|
| 4 |
Tags: search, relevance, better search
|
| 5 |
Requires at least: 3.3
|
| 6 |
Tested up to: 4.4
|
| 7 |
+
Stable tag: 3.5.1
|
| 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.1 =
|
| 390 |
+
* Fixed an error in the Did you mean function.
|
| 391 |
+
* Fixed an error if the search term was not found in content.
|
| 392 |
+
* Fixed an error when building excerpts from posts shorter than the excerpt length.
|
| 393 |
+
* Blocked the `[starpro]` shortcode that was causing problems with Relevanssi.
|
| 394 |
+
* New filter: `relevanssi_remove_stopwords_in_titles` allows you to include stopwords in titles.
|
| 395 |
+
* Added support for `term_tax_id` in the `fields` parameter in tax_queries.
|
| 396 |
+
* Excerpt-building failed if multibyte string operations were missing. It should work now.
|
| 397 |
+
|
| 398 |
= 3.5 =
|
| 399 |
* 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.
|
| 400 |
* Small improvement to WPML multilanguage filtering.
|
| 1100 |
|
| 1101 |
== Upgrade notice ==
|
| 1102 |
|
| 1103 |
+
= 3.5.1 =
|
| 1104 |
+
* Small bug fixes and a new filter.
|
| 1105 |
+
|
| 1106 |
= 3.5 =
|
| 1107 |
* Improved excerpt-building, several bug fixes, couple of small updates.
|
| 1108 |
|
relevanssi.php
CHANGED
|
@@ -3,12 +3,12 @@
|
|
| 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
|
| 12 |
|
| 13 |
This file is part of Relevanssi, a search plugin for WordPress.
|
| 14 |
|
|
@@ -93,11 +93,11 @@ function relevanssi_didyoumean($query, $pre, $post, $n = 5, $echo = true) {
|
|
| 93 |
|
| 94 |
), $url ));
|
| 95 |
$url = apply_filters('relevanssi_didyoumean_url', $url);
|
| 96 |
-
$result = apply_filters('relevanssi_didyoumean_suggestion', "$pre<a href='$url'>$
|
| 97 |
if ($echo) echo $result;
|
| 98 |
}
|
| 99 |
|
| 100 |
-
|
| 101 |
}
|
| 102 |
|
| 103 |
function relevanssi_check_old_data() {
|
| 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.1
|
| 7 |
Author: Mikko Saari
|
| 8 |
Author URI: http://www.mikkosaari.fi/
|
| 9 |
*/
|
| 10 |
|
| 11 |
+
/* Copyright 2016 Mikko Saari (email: mikko@mikkosaari.fi)
|
| 12 |
|
| 13 |
This file is part of Relevanssi, a search plugin for WordPress.
|
| 14 |
|
| 93 |
|
| 94 |
), $url ));
|
| 95 |
$url = apply_filters('relevanssi_didyoumean_url', $url);
|
| 96 |
+
$result = apply_filters('relevanssi_didyoumean_suggestion', "$pre<a href='$url'>$closest</a>$post");
|
| 97 |
if ($echo) echo $result;
|
| 98 |
}
|
| 99 |
|
| 100 |
+
return $result;
|
| 101 |
}
|
| 102 |
|
| 103 |
function relevanssi_check_old_data() {
|
