Version Description
- New feature: New filter hook
relevanssi_term_where
lets you filter the term WHERE conditional for the search query. - Minor fix: Doing the document count updates asynchronously caused problems in some cases (eg. importing posts). Now the document count is only updated after a full indexing and once per week.
- Minor fix: Phrase matching has been improved to make it possible to search for phrases that include characters like the ampersand.
Download this release
Release Info
Developer | msaari |
Plugin | Relevanssi – A Better Search |
Version | 4.8.2 |
Comparing to | |
See all releases |
Code changes from version 4.8.1 to 4.8.2
- lib/common.php +39 -9
- lib/excerpts-highlights.php +14 -0
- lib/indexing.php +0 -9
- lib/init.php +4 -0
- lib/interface.php +5 -0
- lib/search.php +11 -3
- lib/tabs/indexing-tab.php +6 -1
- lib/uninstall.php +2 -2
- readme.txt +9 -1
- relevanssi.php +2 -2
lib/common.php
CHANGED
@@ -508,14 +508,8 @@ function relevanssi_generate_phrase_queries( $phrases, $taxonomies, $custom_fiel
|
|
508 |
foreach ( $phrases as $phrase ) {
|
509 |
$queries = array();
|
510 |
$phrase = $wpdb->esc_like( $phrase );
|
511 |
-
$phrase = str_replace( '‘', '_', $phrase );
|
512 |
-
$phrase =
|
513 |
-
$phrase = str_replace( "'", '_', $phrase );
|
514 |
-
$phrase = str_replace( '"', '_', $phrase );
|
515 |
-
$phrase = str_replace( '”', '_', $phrase );
|
516 |
-
$phrase = str_replace( '“', '_', $phrase );
|
517 |
-
$phrase = str_replace( '„', '_', $phrase );
|
518 |
-
$phrase = str_replace( '´', '_', $phrase );
|
519 |
$phrase = esc_sql( $phrase );
|
520 |
|
521 |
$excerpt = '';
|
@@ -1307,7 +1301,43 @@ function relevanssi_stripos( $haystack, $needle, $offset = 0 ) {
|
|
1307 |
return false;
|
1308 |
}
|
1309 |
|
1310 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1311 |
if ( '' === $haystack ) {
|
1312 |
$pos = false;
|
1313 |
} else {
|
508 |
foreach ( $phrases as $phrase ) {
|
509 |
$queries = array();
|
510 |
$phrase = $wpdb->esc_like( $phrase );
|
511 |
+
$phrase = str_replace( array( '‘', '’', "'", '"', '”', '“', '“', '„', '´' ), '_', $phrase );
|
512 |
+
$phrase = htmlentities( $phrase );
|
|
|
|
|
|
|
|
|
|
|
|
|
513 |
$phrase = esc_sql( $phrase );
|
514 |
|
515 |
$excerpt = '';
|
1301 |
return false;
|
1302 |
}
|
1303 |
|
1304 |
+
if ( preg_match( '/[\?\*]/', $needle ) ) {
|
1305 |
+
// There's a ? or an * in the string, which means it's a wildcard search
|
1306 |
+
// query (a Premium feature) and requires some extra steps.
|
1307 |
+
|
1308 |
+
$needle_regex = str_replace(
|
1309 |
+
array( '?', '*' ),
|
1310 |
+
array( '.', '.*' ),
|
1311 |
+
$needle
|
1312 |
+
);
|
1313 |
+
$pos_found = false;
|
1314 |
+
while ( ! $pos_found ) {
|
1315 |
+
preg_match(
|
1316 |
+
"/$needle_regex/i",
|
1317 |
+
$haystack,
|
1318 |
+
$matches,
|
1319 |
+
PREG_OFFSET_CAPTURE,
|
1320 |
+
$offset
|
1321 |
+
);
|
1322 |
+
/**
|
1323 |
+
* This trickery is necessary, because PREG_OFFSET_CAPTURE gives
|
1324 |
+
* wrong offsets for multibyte strings. The mb_strlen() gives the
|
1325 |
+
* correct offset, the rest of this is because the $offset received
|
1326 |
+
* as a parameter can be before the first $position, leading to an
|
1327 |
+
* infinite loop.
|
1328 |
+
*/
|
1329 |
+
$pos = isset( $matches[0][1] )
|
1330 |
+
? mb_strlen( substr( $haystack, 0, $matches[0][1] ) )
|
1331 |
+
: false;
|
1332 |
+
if ( $pos && $pos > $offset ) {
|
1333 |
+
$pos_found = true;
|
1334 |
+
} elseif ( $pos ) {
|
1335 |
+
$offset++;
|
1336 |
+
} else {
|
1337 |
+
$pos_found = true;
|
1338 |
+
}
|
1339 |
+
}
|
1340 |
+
} elseif ( function_exists( 'mb_stripos' ) ) {
|
1341 |
if ( '' === $haystack ) {
|
1342 |
$pos = false;
|
1343 |
} else {
|
lib/excerpts-highlights.php
CHANGED
@@ -524,6 +524,13 @@ function relevanssi_highlight_terms( $content, $query, $in_docs = false ) {
|
|
524 |
$pr_term = preg_quote( $term, '/' );
|
525 |
$pr_term = relevanssi_add_accent_variations( $pr_term );
|
526 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
527 |
if ( $word_boundaries_available ) {
|
528 |
$regex = "/(\b$pr_term\b)/iu";
|
529 |
if ( 'never' !== get_option( 'relevanssi_fuzzy' ) ) {
|
@@ -879,6 +886,13 @@ function relevanssi_count_matches( $words, $complete_text ) {
|
|
879 |
),
|
880 |
'UTF-8'
|
881 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
882 |
if ( $word_boundaries_available ) {
|
883 |
if ( 'never' !== get_option( 'relevanssi_fuzzy' ) ) {
|
884 |
$regex = "/\b$word_slice|$word_slice\b/";
|
524 |
$pr_term = preg_quote( $term, '/' );
|
525 |
$pr_term = relevanssi_add_accent_variations( $pr_term );
|
526 |
|
527 |
+
// Support for wildcard matching (a Premium feature).
|
528 |
+
$pr_term = str_replace(
|
529 |
+
array( '\*', '\?' ),
|
530 |
+
array( '\S*', '.' ),
|
531 |
+
$pr_term
|
532 |
+
);
|
533 |
+
|
534 |
if ( $word_boundaries_available ) {
|
535 |
$regex = "/(\b$pr_term\b)/iu";
|
536 |
if ( 'never' !== get_option( 'relevanssi_fuzzy' ) ) {
|
886 |
),
|
887 |
'UTF-8'
|
888 |
);
|
889 |
+
// Support for wildcard matching (a Premium feature).
|
890 |
+
$word_slice = str_replace(
|
891 |
+
array( '\*', '\?' ),
|
892 |
+
array( '\S*', '.' ),
|
893 |
+
$word_slice
|
894 |
+
);
|
895 |
+
|
896 |
if ( $word_boundaries_available ) {
|
897 |
if ( 'never' !== get_option( 'relevanssi_fuzzy' ) ) {
|
898 |
$regex = "/\b$word_slice|$word_slice\b/";
|
lib/indexing.php
CHANGED
@@ -816,7 +816,6 @@ function relevanssi_publish( $post_id, $bypass_global_post = false ) {
|
|
816 |
*/
|
817 |
function relevanssi_insert_edit( $post_id ) {
|
818 |
global $wpdb;
|
819 |
-
|
820 |
if ( 'revision' === relevanssi_get_post_type( $post_id ) ) {
|
821 |
return 'revision';
|
822 |
}
|
@@ -862,10 +861,6 @@ function relevanssi_insert_edit( $post_id ) {
|
|
862 |
if ( $index_this_post ) {
|
863 |
$bypass_global_post = true;
|
864 |
$return_value = relevanssi_publish( $post_id, $bypass_global_post );
|
865 |
-
|
866 |
-
if ( is_int( $return_value ) && $return_value > 0 ) {
|
867 |
-
relevanssi_async_update_doc_count();
|
868 |
-
}
|
869 |
} else {
|
870 |
// The post isn't supposed to be indexed anymore, remove it from index.
|
871 |
relevanssi_remove_doc( $post_id );
|
@@ -1046,10 +1041,6 @@ function relevanssi_remove_doc( $post_id, $keep_internal_links = false ) {
|
|
1046 |
$post_id
|
1047 |
)
|
1048 |
);
|
1049 |
-
|
1050 |
-
if ( $rows_updated && $rows_updated > 0 ) {
|
1051 |
-
relevanssi_async_update_doc_count();
|
1052 |
-
}
|
1053 |
}
|
1054 |
}
|
1055 |
|
816 |
*/
|
817 |
function relevanssi_insert_edit( $post_id ) {
|
818 |
global $wpdb;
|
|
|
819 |
if ( 'revision' === relevanssi_get_post_type( $post_id ) ) {
|
820 |
return 'revision';
|
821 |
}
|
861 |
if ( $index_this_post ) {
|
862 |
$bypass_global_post = true;
|
863 |
$return_value = relevanssi_publish( $post_id, $bypass_global_post );
|
|
|
|
|
|
|
|
|
864 |
} else {
|
865 |
// The post isn't supposed to be indexed anymore, remove it from index.
|
866 |
relevanssi_remove_doc( $post_id );
|
1041 |
$post_id
|
1042 |
)
|
1043 |
);
|
|
|
|
|
|
|
|
|
1044 |
}
|
1045 |
}
|
1046 |
|
lib/init.php
CHANGED
@@ -141,6 +141,10 @@ function relevanssi_init() {
|
|
141 |
}
|
142 |
}
|
143 |
|
|
|
|
|
|
|
|
|
144 |
if ( function_exists( 'icl_object_id' ) && ! function_exists( 'pll_is_translated_post_type' ) ) {
|
145 |
require_once 'compatibility/wpml.php';
|
146 |
}
|
141 |
}
|
142 |
}
|
143 |
|
144 |
+
if ( ! wp_next_scheduled( 'relevanssi_update_counts' ) ) {
|
145 |
+
wp_schedule_event( time(), 'weekly', 'relevanssi_update_counts' );
|
146 |
+
}
|
147 |
+
|
148 |
if ( function_exists( 'icl_object_id' ) && ! function_exists( 'pll_is_translated_post_type' ) ) {
|
149 |
require_once 'compatibility/wpml.php';
|
150 |
}
|
lib/interface.php
CHANGED
@@ -87,6 +87,11 @@ function relevanssi_options() {
|
|
87 |
check_admin_referer( plugin_basename( $relevanssi_variables['file'] ), 'relevanssi_options' );
|
88 |
relevanssi_remove_all_body_stopwords();
|
89 |
}
|
|
|
|
|
|
|
|
|
|
|
90 |
}
|
91 |
|
92 |
relevanssi_options_form();
|
87 |
check_admin_referer( plugin_basename( $relevanssi_variables['file'] ), 'relevanssi_options' );
|
88 |
relevanssi_remove_all_body_stopwords();
|
89 |
}
|
90 |
+
|
91 |
+
if ( isset( $_REQUEST['update_counts'] ) ) {
|
92 |
+
check_admin_referer( 'update_counts' );
|
93 |
+
relevanssi_update_counts();
|
94 |
+
}
|
95 |
}
|
96 |
|
97 |
relevanssi_options_form();
|
lib/search.php
CHANGED
@@ -182,8 +182,11 @@ function relevanssi_search( $args ) {
|
|
182 |
// Get the count from the options.
|
183 |
$doc_count = get_option( 'relevanssi_doc_count', 0 );
|
184 |
if ( ! $doc_count || $doc_count < 1 ) {
|
185 |
-
|
186 |
-
|
|
|
|
|
|
|
187 |
}
|
188 |
|
189 |
$total_hits = 0;
|
@@ -1147,7 +1150,12 @@ function relevanssi_generate_term_where( $term, $force_fuzzy = false, $no_terms
|
|
1147 |
|
1148 |
$term_where = str_replace( '#term#', $term, $term_where_template );
|
1149 |
|
1150 |
-
|
|
|
|
|
|
|
|
|
|
|
1151 |
}
|
1152 |
|
1153 |
/**
|
182 |
// Get the count from the options.
|
183 |
$doc_count = get_option( 'relevanssi_doc_count', 0 );
|
184 |
if ( ! $doc_count || $doc_count < 1 ) {
|
185 |
+
$doc_count = relevanssi_update_doc_count();
|
186 |
+
if ( ! $doc_count || $doc_count < 1 ) {
|
187 |
+
// No value available for some reason, use a random value.
|
188 |
+
$doc_count = 100;
|
189 |
+
}
|
190 |
}
|
191 |
|
192 |
$total_hits = 0;
|
1150 |
|
1151 |
$term_where = str_replace( '#term#', $term, $term_where_template );
|
1152 |
|
1153 |
+
/**
|
1154 |
+
* Filters the term WHERE condition for the Relevanssi MySQL query.
|
1155 |
+
*
|
1156 |
+
* @param string $term_where The WHERE condition for the terms.
|
1157 |
+
*/
|
1158 |
+
return apply_filters( 'relevanssi_term_where', $term_where );
|
1159 |
}
|
1160 |
|
1161 |
/**
|
lib/tabs/indexing-tab.php
CHANGED
@@ -98,6 +98,9 @@ function relevanssi_indexing_tab() {
|
|
98 |
$taxterm_count = get_option( 'relevanssi_taxterm_count', 0 );
|
99 |
}
|
100 |
|
|
|
|
|
|
|
101 |
?>
|
102 |
<div id="indexing_tab">
|
103 |
|
@@ -123,7 +126,7 @@ function relevanssi_indexing_tab() {
|
|
123 |
</div>
|
124 |
<div id='relevanssi-note' style='display: none'></div>
|
125 |
<div id='relevanssi-progress' class='rpi-progress'><div class="rpi-indicator"></div></div>
|
126 |
-
<div id='relevanssi-timer'><?php esc_html_e( 'Time elapsed', 'relevanssi' ); ?>: <span id="relevanssi_elapsed">0:00:00</span> |
|
127 |
<label for="results" class="screen-reader-text"><?php esc_html_e( 'Results', 'relevanssi' ); ?></label><textarea id='results' rows='10' cols='80'></textarea>
|
128 |
<div id='relevanssi-indexing-instructions' style='display: none'><?php esc_html_e( "Indexing should respond quickly. If nothing happens in couple of minutes, it's probably stuck. The most common reasons for indexing issues are incompatible shortcodes, so try disabling the shortcode expansion setting and try again. Also, if you've just updated Relevanssi, doing a hard refresh in your browser will make sure your browser is not trying to use an outdated version of the Relevanssi scripts.", 'relevanssi' ); ?></div>
|
129 |
</td>
|
@@ -138,6 +141,8 @@ function relevanssi_indexing_tab() {
|
|
138 |
</p>
|
139 |
<p><?php echo esc_html( $terms_count ); ?> <?php echo esc_html( _n( 'term in the index.', 'terms in the index.', $terms_count, 'relevanssi' ) ); ?><br />
|
140 |
<?php echo esc_html( $lowest_doc ); ?> <?php esc_html_e( 'is the lowest post ID indexed.', 'relevanssi' ); ?></p>
|
|
|
|
|
141 |
</td>
|
142 |
</tr>
|
143 |
</table>
|
98 |
$taxterm_count = get_option( 'relevanssi_taxterm_count', 0 );
|
99 |
}
|
100 |
|
101 |
+
$this_page = '?page=' . plugin_basename( $relevanssi_variables['file'] );
|
102 |
+
$update_url = wp_nonce_url( $this_page . '&tab=indexing&update_counts=1', 'update_counts' );
|
103 |
+
|
104 |
?>
|
105 |
<div id="indexing_tab">
|
106 |
|
126 |
</div>
|
127 |
<div id='relevanssi-note' style='display: none'></div>
|
128 |
<div id='relevanssi-progress' class='rpi-progress'><div class="rpi-indicator"></div></div>
|
129 |
+
<div id='relevanssi-timer'><?php esc_html_e( 'Time elapsed', 'relevanssi' ); ?>: <span id="relevanssi_elapsed">0:00:00</span> | <?php esc_html_e( 'Time remaining', 'relevanssi' ); ?>: <span id="relevanssi_estimated"><?php esc_html_e( 'some time', 'relevanssi' ); ?></span></div>
|
130 |
<label for="results" class="screen-reader-text"><?php esc_html_e( 'Results', 'relevanssi' ); ?></label><textarea id='results' rows='10' cols='80'></textarea>
|
131 |
<div id='relevanssi-indexing-instructions' style='display: none'><?php esc_html_e( "Indexing should respond quickly. If nothing happens in couple of minutes, it's probably stuck. The most common reasons for indexing issues are incompatible shortcodes, so try disabling the shortcode expansion setting and try again. Also, if you've just updated Relevanssi, doing a hard refresh in your browser will make sure your browser is not trying to use an outdated version of the Relevanssi scripts.", 'relevanssi' ); ?></div>
|
132 |
</td>
|
141 |
</p>
|
142 |
<p><?php echo esc_html( $terms_count ); ?> <?php echo esc_html( _n( 'term in the index.', 'terms in the index.', $terms_count, 'relevanssi' ) ); ?><br />
|
143 |
<?php echo esc_html( $lowest_doc ); ?> <?php esc_html_e( 'is the lowest post ID indexed.', 'relevanssi' ); ?></p>
|
144 |
+
<?php /** Translators: %1$s opens the a tag, %2$s closes it. */ ?>
|
145 |
+
<p class="description">(<?php printf( esc_html__( 'These values may be inaccurate. If you need exact values, %1$supdate the counts%2$s' ), '<a href="' . esc_attr( $update_url ) . '">', '</a>' ); ?>.)</p>
|
146 |
</td>
|
147 |
</tr>
|
148 |
</table>
|
lib/uninstall.php
CHANGED
@@ -23,8 +23,6 @@ function relevanssi_drop_database_tables() {
|
|
23 |
return;
|
24 |
}
|
25 |
|
26 |
-
wp_clear_scheduled_hook( 'relevanssi_truncate_cache' );
|
27 |
-
|
28 |
$relevanssi_table = $wpdb->prefix . 'relevanssi';
|
29 |
$stopword_table = $wpdb->prefix . 'relevanssi_stopwords';
|
30 |
$log_table = $wpdb->prefix . 'relevanssi_log';
|
@@ -136,5 +134,7 @@ function relevanssi_uninstall_free() {
|
|
136 |
global $wpdb;
|
137 |
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_noindex_reason'" );
|
138 |
|
|
|
|
|
139 |
relevanssi_drop_database_tables();
|
140 |
}
|
23 |
return;
|
24 |
}
|
25 |
|
|
|
|
|
26 |
$relevanssi_table = $wpdb->prefix . 'relevanssi';
|
27 |
$stopword_table = $wpdb->prefix . 'relevanssi_stopwords';
|
28 |
$log_table = $wpdb->prefix . 'relevanssi_log';
|
134 |
global $wpdb;
|
135 |
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_noindex_reason'" );
|
136 |
|
137 |
+
wp_clear_scheduled_hook( 'relevanssi_update_counts' );
|
138 |
+
|
139 |
relevanssi_drop_database_tables();
|
140 |
}
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: search, relevance, better search, product search, woocommerce search
|
|
5 |
Requires at least: 4.9
|
6 |
Tested up to: 5.5
|
7 |
Requires PHP: 7.0
|
8 |
-
Stable tag: 4.8.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -133,6 +133,11 @@ Each document database is full of useless words. All the little words that appea
|
|
133 |
* John Calahan for extensive 4.0 beta testing.
|
134 |
|
135 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
136 |
= 4.8.1 =
|
137 |
* Major fix: Changes in WooCommerce 4.4.0 broke the Relevanssi searches. This makes the WooCommerce search work again.
|
138 |
* Minor fix: Excluding from logs didn't work if user IDs had spaces between them ('user_a, user_b'). Now the extra spaces don't matter.
|
@@ -175,6 +180,9 @@ Each document database is full of useless words. All the little words that appea
|
|
175 |
* Minor fix: User Access Manager showed drafts in search results for all users. This is now fixed.
|
176 |
|
177 |
== Upgrade notice ==
|
|
|
|
|
|
|
178 |
= 4.8.1 =
|
179 |
* WooCommerce 4.4 compatibility, other minor fixes.
|
180 |
|
5 |
Requires at least: 4.9
|
6 |
Tested up to: 5.5
|
7 |
Requires PHP: 7.0
|
8 |
+
Stable tag: 4.8.2
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
133 |
* John Calahan for extensive 4.0 beta testing.
|
134 |
|
135 |
== Changelog ==
|
136 |
+
= 4.8.2 =
|
137 |
+
* New feature: New filter hook `relevanssi_term_where` lets you filter the term WHERE conditional for the search query.
|
138 |
+
* Minor fix: Doing the document count updates asynchronously caused problems in some cases (eg. importing posts). Now the document count is only updated after a full indexing and once per week.
|
139 |
+
* Minor fix: Phrase matching has been improved to make it possible to search for phrases that include characters like the ampersand.
|
140 |
+
|
141 |
= 4.8.1 =
|
142 |
* Major fix: Changes in WooCommerce 4.4.0 broke the Relevanssi searches. This makes the WooCommerce search work again.
|
143 |
* Minor fix: Excluding from logs didn't work if user IDs had spaces between them ('user_a, user_b'). Now the extra spaces don't matter.
|
180 |
* Minor fix: User Access Manager showed drafts in search results for all users. This is now fixed.
|
181 |
|
182 |
== Upgrade notice ==
|
183 |
+
= 4.8.2 =
|
184 |
+
* Performance and phrase search improvements.
|
185 |
+
|
186 |
= 4.8.1 =
|
187 |
* WooCommerce 4.4 compatibility, other minor fixes.
|
188 |
|
relevanssi.php
CHANGED
@@ -13,7 +13,7 @@
|
|
13 |
* Plugin Name: Relevanssi
|
14 |
* Plugin URI: https://www.relevanssi.com/
|
15 |
* Description: This plugin replaces WordPress search with a relevance-sorting search.
|
16 |
-
* Version: 4.8.
|
17 |
* Author: Mikko Saari
|
18 |
* Author URI: http://www.mikkosaari.fi/
|
19 |
* Text Domain: relevanssi
|
@@ -67,7 +67,7 @@ $relevanssi_variables['database_version'] = 5;
|
|
67 |
$relevanssi_variables['file'] = __FILE__;
|
68 |
$relevanssi_variables['plugin_dir'] = plugin_dir_path( __FILE__ );
|
69 |
$relevanssi_variables['plugin_basename'] = plugin_basename( __FILE__ );
|
70 |
-
$relevanssi_variables['plugin_version'] = '4.8.
|
71 |
|
72 |
require_once 'lib/admin-ajax.php';
|
73 |
require_once 'lib/common.php';
|
13 |
* Plugin Name: Relevanssi
|
14 |
* Plugin URI: https://www.relevanssi.com/
|
15 |
* Description: This plugin replaces WordPress search with a relevance-sorting search.
|
16 |
+
* Version: 4.8.2
|
17 |
* Author: Mikko Saari
|
18 |
* Author URI: http://www.mikkosaari.fi/
|
19 |
* Text Domain: relevanssi
|
67 |
$relevanssi_variables['file'] = __FILE__;
|
68 |
$relevanssi_variables['plugin_dir'] = plugin_dir_path( __FILE__ );
|
69 |
$relevanssi_variables['plugin_basename'] = plugin_basename( __FILE__ );
|
70 |
+
$relevanssi_variables['plugin_version'] = '4.8.2';
|
71 |
|
72 |
require_once 'lib/admin-ajax.php';
|
73 |
require_once 'lib/common.php';
|