Relevanssi – A Better Search - Version 3.5.1

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_titles allows you to include stopwords in titles.
  • Added support for term_tax_id in the fields parameter in tax_queries.
  • Excerpt-building failed if multibyte string operations were missing. It should work now.
Download this release

Release Info

Developer msaari
Plugin Icon 128x128 Relevanssi – A Better Search
Version 3.5.1
Comparing to
See all releases

Code changes from version 3.5 to 3.5.1

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
- $textlength = mb_strlen($fulltext);
 
 
 
 
 
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
- $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;
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 (!is_array($term_id)) {
136
- $term_id = array($term_id);
 
 
 
 
 
 
 
 
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 2015 Mikko Saari (email: mikko@mikkosaari.fi)
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'>$suggestion</a>$post");
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() {