Relevanssi – A Better Search - Version 4.3.4

Version Description

  • New feature: You can now give Gutenberg blocks a CSS class relevanssi_noindex to exclude them from being indexed. Relevanssi will not index Gutenberg blocks that have the class.
  • New feature: Relevanssi automatically skips some custom fields from common plugins that only contain unnecessary metadata.
  • New feature: The search results breakdown is added to the post objects and can be found in $post->relevanssi_hits. The data also includes new fields and the breakdown from the excerpt settings page can now show author, excerpt, custom field and MySQL column hits.
  • New feature: Relevanssi can now index Ninja Tables table content. This is something of an experimental feature right now, feedback is welcome.
  • New feature: New filter hook relevanssi_indexing_query filters the indexing query and is mostly interesting for debugging reasons.
  • Minor fix: Deleted and trashed comment contents were not deindexed when the comment was removed. That has been corrected now.
  • Minor fix: Phrase matching is now applied to attachments as well, including the attachments indexed for parent post.
  • Minor fix: Phrase matching only looks at custom fields that are indexed by Relevanssi.
  • Minor fix: Exact match bonus now uses the original query without synonyms added for the exact match check.
  • Minor fix: Paid Membership Pro filtering is only applied to published posts to prevent drafts from showing up in the search results.
Download this release

Release Info

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

Code changes from version 4.3.3 to 4.3.4

lib/common.php CHANGED
@@ -51,68 +51,121 @@ function relevanssi_strtolower( $string ) {
51
  }
52
 
53
  /**
54
- * Generates the search result breakdown added to the search results.
55
- *
56
- * Gets the source data, generates numbers of it and then replaces the placeholders
57
- * in the breakdown template with the data.
58
  *
59
- * @param array $data The source data.
60
- * @param int $hit The post ID.
 
61
  *
62
- * @return string The search results breakdown for the post.
 
63
  */
64
- function relevanssi_show_matches( $data, $hit ) {
65
- if ( isset( $data['body_matches'][ $hit ] ) ) {
66
- $body = $data['body_matches'][ $hit ];
67
- } else {
68
- $body = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  }
70
- if ( isset( $data['title_matches'][ $hit ] ) ) {
71
- $title = $data['title_matches'][ $hit ];
72
- } else {
73
- $title = 0;
74
  }
75
- if ( isset( $data['tag_matches'][ $hit ] ) ) {
76
- $tag = $data['tag_matches'][ $hit ];
77
- } else {
78
- $tag = 0;
79
  }
80
- if ( isset( $data['category_matches'][ $hit ] ) ) {
81
- $category = $data['category_matches'][ $hit ];
82
- } else {
83
- $category = 0;
84
  }
85
- if ( isset( $data['taxonomy_matches'][ $hit ] ) ) {
86
- $taxonomy = $data['taxonomy_matches'][ $hit ];
87
- } else {
88
- $taxonomy = 0;
89
  }
90
- if ( isset( $data['comment_matches'][ $hit ] ) ) {
91
- $comment = $data['comment_matches'][ $hit ];
92
- } else {
93
- $comment = 0;
94
  }
95
- if ( isset( $data['scores'][ $hit ] ) ) {
96
- $score = round( $data['scores'][ $hit ], 2 );
97
- } else {
98
- $score = 0;
99
  }
100
- if ( isset( $data['term_hits'][ $hit ] ) ) {
101
- $term_hits_array = $data['term_hits'][ $hit ];
102
- arsort( $term_hits_array );
103
- } else {
104
- $term_hits_array = array();
105
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  $term_hits = '';
107
  $total_hits = 0;
108
- foreach ( $term_hits_array as $term => $hits ) {
109
  $term_hits .= " $term: $hits";
110
  $total_hits += $hits;
111
  }
112
 
113
  $text = stripslashes( get_option( 'relevanssi_show_matches_text' ) );
114
- $replace_these = array( '%body%', '%title%', '%tags%', '%categories%', '%taxonomies%', '%comments%', '%score%', '%terms%', '%total%' );
115
- $replacements = array( $body, $title, $tag, $category, $taxonomy, $comment, $score, $term_hits, $total_hits );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  $result = ' ' . str_replace( $replace_these, $replacements, $text );
117
 
118
  /**
@@ -323,51 +376,91 @@ function relevanssi_recognize_phrases( $search_query, $operator = 'AND' ) {
323
  $phrases = relevanssi_extract_phrases( $search_query );
324
  $status = relevanssi_valid_status_array();
325
 
 
 
 
 
 
326
  $all_queries = array();
327
- if ( count( $phrases ) > 0 ) {
328
- foreach ( $phrases as $phrase ) {
329
- $queries = array();
330
- $phrase = $wpdb->esc_like( $phrase );
331
- $phrase = str_replace( '‘', '_', $phrase );
332
- $phrase = str_replace( '’', '_', $phrase );
333
- $phrase = str_replace( "'", '_', $phrase );
334
- $phrase = str_replace( '"', '_', $phrase );
335
- $phrase = str_replace( '', '_', $phrase );
336
- $phrase = str_replace( '“', '_', $phrase );
337
- $phrase = str_replace( '', '_', $phrase );
338
- $phrase = str_replace( '´', '_', $phrase );
339
- $phrase = esc_sql( $phrase );
340
- $excerpt = '';
341
- if ( 'on' === get_option( 'relevanssi_index_excerpt' ) ) {
342
- $excerpt = " OR post_excerpt LIKE '%$phrase%'";
343
- }
 
 
 
 
344
 
345
- $query = "(SELECT ID FROM $wpdb->posts
346
- WHERE (post_content LIKE '%$phrase%' OR post_title LIKE '%$phrase%' $excerpt)
347
- AND post_status IN ($status))";
348
 
349
- $queries[] = $query;
 
 
 
 
 
350
 
351
  $query = "(SELECT ID FROM $wpdb->posts as p, $wpdb->term_relationships as r, $wpdb->term_taxonomy as s, $wpdb->terms as t
352
  WHERE r.term_taxonomy_id = s.term_taxonomy_id AND s.term_id = t.term_id AND p.ID = r.object_id
 
353
  AND t.name LIKE '%$phrase%' AND p.post_status IN ($status))";
354
 
355
  $queries[] = $query;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
 
357
  $query = "(SELECT ID
358
- FROM $wpdb->posts AS p, $wpdb->postmeta AS m
359
- WHERE p.ID = m.post_id
360
- AND m.meta_value LIKE '%$phrase%'
361
- AND p.post_status IN ($status))";
 
362
 
363
  $queries[] = $query;
 
364
 
365
- $queries = implode( ' OR relevanssi.doc IN ', $queries );
366
- $queries = "(relevanssi.doc IN $queries)";
367
- $all_queries[] = $queries;
 
 
 
 
 
 
 
368
  }
369
- } else {
370
- $phrases = '';
 
 
371
  }
372
 
373
  $operator = strtoupper( $operator );
@@ -896,7 +989,7 @@ function relevanssi_the_tags( $before = null, $separator = ', ', $after = '', $e
896
 
897
  $count = count( $matches[0] );
898
  for ( $i = 0; $i < $count; $i++ ) {
899
- $highlighted_tag_name = relevanssi_highlight_terms( $tag_names[ $i ], get_search_query() );
900
  $highlighted[ $i ] = str_replace( '>' . $tag_names[ $i ] . '<', '>' . $highlighted_tag_name . '<', $originals[ $i ] );
901
  }
902
 
@@ -1653,9 +1746,19 @@ function relevanssi_get_forbidden_post_types() {
1653
  'jp_pay_product', // Jetpack.
1654
  'jp_mem_plan', // Jetpack.
1655
  'tablepress_table', // TablePress.
 
1656
  'shop_order', // WooCommerce.
1657
  'shop_order_refund', // WooCommerce.
1658
  'shop_webhook', // WooCommerce.
 
 
 
 
 
 
 
 
 
1659
  );
1660
  }
1661
 
@@ -1670,6 +1773,7 @@ function relevanssi_get_forbidden_taxonomies() {
1670
  'link_category', // Link categories.
1671
  'amp_validation_error', // AMP.
1672
  'product_visibility', // WooCommerce.
 
1673
  );
1674
  }
1675
 
@@ -1683,3 +1787,26 @@ function relevanssi_get_forbidden_taxonomies() {
1683
  function relevanssi_return_off() {
1684
  return 'off';
1685
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  }
52
 
53
  /**
54
+ * Adds the search result match breakdown to the post object.
 
 
 
55
  *
56
+ * Reads in the number of matches and stores it in the relevanssi_hits filed
57
+ * of the post object. The post object is passed as a reference and modified
58
+ * on the fly.
59
  *
60
+ * @param object $post The post object, passed as a reference.
61
+ * @param array $data The source data.
62
  */
63
+ function relevanssi_add_matches( &$post, $data ) {
64
+ $hits = array(
65
+ 'body' => 0,
66
+ 'title' => 0,
67
+ 'comment' => 0,
68
+ 'author' => 0,
69
+ 'excerpt' => 0,
70
+ 'customfield' => 0,
71
+ 'mysqlcolumn' => 0,
72
+ 'taxonomy' => array(
73
+ 'tag' => 0,
74
+ 'category' => 0,
75
+ 'taxonomy' => 0,
76
+ ),
77
+ 'score' => 0,
78
+ 'terms' => array(),
79
+ );
80
+ if ( isset( $data['body_matches'][ $post->ID ] ) ) {
81
+ $hits['body'] = $data['body_matches'][ $post->ID ];
82
  }
83
+ if ( isset( $data['title_matches'][ $post->ID ] ) ) {
84
+ $hits['title'] = $data['title_matches'][ $post->ID ];
 
 
85
  }
86
+ if ( isset( $data['tag_matches'][ $post->ID ] ) ) {
87
+ $hits['taxonomy']['tag'] = $data['tag_matches'][ $post->ID ];
 
 
88
  }
89
+ if ( isset( $data['category_matches'][ $post->ID ] ) ) {
90
+ $hits['taxonomy']['category'] = $data['category_matches'][ $post->ID ];
 
 
91
  }
92
+ if ( isset( $data['taxonomy_matches'][ $post->ID ] ) ) {
93
+ $hits['taxonomy']['taxonomy'] = $data['taxonomy_matches'][ $post->ID ];
 
 
94
  }
95
+ if ( isset( $data['comment_matches'][ $post->ID ] ) ) {
96
+ $hits['comment'] = $data['comment_matches'][ $post->ID ];
 
 
97
  }
98
+ if ( isset( $data['author_matches'][ $post->ID ] ) ) {
99
+ $hits['author'] = $data['author_matches'][ $post->ID ];
 
 
100
  }
101
+ if ( isset( $data['excerpt_matches'][ $post->ID ] ) ) {
102
+ $hits['excerpt'] = $data['excerpt_matches'][ $post->ID ];
103
+ }
104
+ if ( isset( $data['customfield_matches'][ $post->ID ] ) ) {
105
+ $hits['customfield'] = $data['customfield_matches'][ $post->ID ];
106
  }
107
+ if ( isset( $data['mysqlcolumn_matches'][ $post->ID ] ) ) {
108
+ $hits['mysqlcolumn'] = $data['mysqlcolumn_matches'][ $post->ID ];
109
+ }
110
+ if ( isset( $data['scores'][ $post->ID ] ) ) {
111
+ $hits['score'] = round( $data['scores'][ $post->ID ], 2 );
112
+ }
113
+ if ( isset( $data['term_hits'][ $post->ID ] ) ) {
114
+ $hits['terms'] = $data['term_hits'][ $post->ID ];
115
+ arsort( $hits['terms'] );
116
+ }
117
+ $post->relevanssi_hits = $hits;
118
+ }
119
+
120
+ /**
121
+ * Generates the search result breakdown added to the search results.
122
+ *
123
+ * Gets the source data from the post object and then replaces the placeholders
124
+ * in the breakdown template with the data.
125
+ *
126
+ * @param object $post The post object.
127
+ *
128
+ * @return string The search results breakdown for the post.
129
+ */
130
+ function relevanssi_show_matches( $post ) {
131
  $term_hits = '';
132
  $total_hits = 0;
133
+ foreach ( $post->relevanssi_hits['terms'] as $term => $hits ) {
134
  $term_hits .= " $term: $hits";
135
  $total_hits += $hits;
136
  }
137
 
138
  $text = stripslashes( get_option( 'relevanssi_show_matches_text' ) );
139
+ $replace_these = array(
140
+ '%body%',
141
+ '%title%',
142
+ '%tags%',
143
+ '%categories%',
144
+ '%taxonomies%',
145
+ '%comments%',
146
+ '%customfields%',
147
+ '%author%',
148
+ '%excerpt%',
149
+ '%mysqlcolumns%',
150
+ '%score%',
151
+ '%terms%',
152
+ '%total%',
153
+ );
154
+ $replacements = array(
155
+ $post->relevanssi_hits['body'],
156
+ $post->relevanssi_hits['title'],
157
+ $post->relevanssi_hits['taxonomy']['tag'],
158
+ $post->relevanssi_hits['taxonomy']['category'],
159
+ $post->relevanssi_hits['taxonomy']['taxonomy'],
160
+ $post->relevanssi_hits['comment'],
161
+ $post->relevanssi_hits['customfield'],
162
+ $post->relevanssi_hits['author'],
163
+ $post->relevanssi_hits['excerpt'],
164
+ $post->relevanssi_hits['mysqlcolumn'],
165
+ $post->relevanssi_hits['score'],
166
+ $term_hits,
167
+ $total_hits,
168
+ );
169
  $result = ' ' . str_replace( $replace_these, $replacements, $text );
170
 
171
  /**
376
  $phrases = relevanssi_extract_phrases( $search_query );
377
  $status = relevanssi_valid_status_array();
378
 
379
+ // Add "inherit" to the list of allowed statuses to include attachments.
380
+ if ( ! strstr( $status, 'inherit' ) ) {
381
+ $status .= ",'inherit'";
382
+ }
383
+
384
  $all_queries = array();
385
+ if ( 0 === count( $phrases ) ) {
386
+ return $all_queries;
387
+ }
388
+
389
+ foreach ( $phrases as $phrase ) {
390
+ $queries = array();
391
+ $phrase = $wpdb->esc_like( $phrase );
392
+ $phrase = str_replace( '', '_', $phrase );
393
+ $phrase = str_replace( '', '_', $phrase );
394
+ $phrase = str_replace( "'", '_', $phrase );
395
+ $phrase = str_replace( '"', '_', $phrase );
396
+ $phrase = str_replace( '', '_', $phrase );
397
+ $phrase = str_replace( '“', '_', $phrase );
398
+ $phrase = str_replace( '', '_', $phrase );
399
+ $phrase = str_replace( '´', '_', $phrase );
400
+ $phrase = esc_sql( $phrase );
401
+
402
+ $excerpt = '';
403
+ if ( 'on' === get_option( 'relevanssi_index_excerpt' ) ) {
404
+ $excerpt = " OR post_excerpt LIKE '%$phrase%'";
405
+ }
406
 
407
+ $query = "(SELECT ID FROM $wpdb->posts
408
+ WHERE (post_content LIKE '%$phrase%' OR post_title LIKE '%$phrase%' $excerpt)
409
+ AND post_status IN ($status))";
410
 
411
+ $queries[] = $query;
412
+
413
+ $taxonomies = get_option( 'relevanssi_index_taxonomies_list', array() );
414
+ if ( $taxonomies ) {
415
+ $taxonomies_escaped = implode( "','", array_map( 'esc_sql', $taxonomies ) );
416
+ $taxonomies_sql = "AND s.taxonomy IN ('$taxonomies_escaped')";
417
 
418
  $query = "(SELECT ID FROM $wpdb->posts as p, $wpdb->term_relationships as r, $wpdb->term_taxonomy as s, $wpdb->terms as t
419
  WHERE r.term_taxonomy_id = s.term_taxonomy_id AND s.term_id = t.term_id AND p.ID = r.object_id
420
+ $taxonomies_sql
421
  AND t.name LIKE '%$phrase%' AND p.post_status IN ($status))";
422
 
423
  $queries[] = $query;
424
+ }
425
+
426
+ $custom_fields = relevanssi_get_custom_fields();
427
+ if ( $custom_fields ) {
428
+ $keys = '';
429
+
430
+ if ( is_array( $custom_fields ) ) {
431
+ $custom_fields_escaped = implode( "','", array_map( 'esc_sql', $custom_fields ) );
432
+ $keys = "AND m.meta_key IN ('$custom_fields_escaped')";
433
+ }
434
+
435
+ if ( 'visible' === $custom_fields ) {
436
+ $keys = "AND (m.meta_key NOT LIKE '_%' OR m.meta_key = '_relevanssi_pdf_content')";
437
+ }
438
 
439
  $query = "(SELECT ID
440
+ FROM $wpdb->posts AS p, $wpdb->postmeta AS m
441
+ WHERE p.ID = m.post_id
442
+ $keys
443
+ AND m.meta_value LIKE '%$phrase%'
444
+ AND p.post_status IN ($status))";
445
 
446
  $queries[] = $query;
447
+ }
448
 
449
+ if ( 'on' === get_option( 'relevanssi_index_pdf_parent' ) ) {
450
+ $query = "(SELECT parent.ID
451
+ FROM $wpdb->posts AS p, $wpdb->postmeta AS m, $wpdb->posts AS parent
452
+ WHERE p.ID = m.post_id
453
+ AND p.post_parent = parent.ID
454
+ AND m.meta_key = '_relevanssi_pdf_content'
455
+ AND m.meta_value LIKE '%$phrase%'
456
+ AND p.post_status = 'inherit')";
457
+
458
+ $queries[] = $query;
459
  }
460
+
461
+ $queries = implode( ' OR relevanssi.doc IN ', $queries );
462
+ $queries = "(relevanssi.doc IN $queries)";
463
+ $all_queries[] = $queries;
464
  }
465
 
466
  $operator = strtoupper( $operator );
989
 
990
  $count = count( $matches[0] );
991
  for ( $i = 0; $i < $count; $i++ ) {
992
+ $highlighted_tag_name = relevanssi_highlight_terms( $tag_names[ $i ], get_search_query(), true );
993
  $highlighted[ $i ] = str_replace( '>' . $tag_names[ $i ] . '<', '>' . $highlighted_tag_name . '<', $originals[ $i ] );
994
  }
995
 
1746
  'jp_pay_product', // Jetpack.
1747
  'jp_mem_plan', // Jetpack.
1748
  'tablepress_table', // TablePress.
1749
+ 'ninja-table', // Ninja Tables.
1750
  'shop_order', // WooCommerce.
1751
  'shop_order_refund', // WooCommerce.
1752
  'shop_webhook', // WooCommerce.
1753
+ 'et_theme_builder', // Divi.
1754
+ 'et_template', // Divi.
1755
+ 'et_header_layout', // Divi.
1756
+ 'et_body_layout', // Divi.
1757
+ 'et_footer_layout', // Divi.
1758
+ 'wpforms', // WP Forms.
1759
+ 'amn_wpforms', // WP Forms.
1760
+ 'wpforms_log', // WP Forms.
1761
+ 'dlm_download_version', // Download Monitor.
1762
  );
1763
  }
1764
 
1773
  'link_category', // Link categories.
1774
  'amp_validation_error', // AMP.
1775
  'product_visibility', // WooCommerce.
1776
+ 'wpforms_log_type', // WP Forms.
1777
  );
1778
  }
1779
 
1787
  function relevanssi_return_off() {
1788
  return 'off';
1789
  }
1790
+
1791
+ /**
1792
+ * Filters out unwanted custom fields.
1793
+ *
1794
+ * Added to the relevanssi_custom_field_value filter hook.
1795
+ *
1796
+ * @see relevanssi_index_custom_fields()
1797
+ *
1798
+ * @param array $values The custom field values.
1799
+ * @param string $field The custom field name.
1800
+ *
1801
+ * @return array Empty array for unwanted custom fields.
1802
+ */
1803
+ function relevanssi_filter_custom_fields( $values, $field ) {
1804
+ $unwanted_custom_fields = array(
1805
+ 'classic-editor-remember' => true,
1806
+ 'php_everywhere_code' => true,
1807
+ );
1808
+ if ( isset( $unwanted_custom_fields[ $field ] ) ) {
1809
+ $values = array();
1810
+ }
1811
+ return $values;
1812
+ }
lib/compatibility/gutenberg.php CHANGED
@@ -19,15 +19,35 @@ if ( RELEVANSSI_PREMIUM ) {
19
  add_filter( 'relevanssi_post_content', 'relevanssi_gutenberg_block_rendering', 10 );
20
 
21
  /**
22
- * Renders Gutenberg reusable blocks.
23
  *
24
- * Gutenberg Reusable Blocks appear as comments in the post content. This function
25
- * picks up the comments and renders the blocks.
 
 
 
 
26
  *
27
  * @param string $content The post content.
28
  *
29
  * @return string The post content with the rendered content added.
30
  */
31
  function relevanssi_gutenberg_block_rendering( $content ) {
32
- return do_blocks( $content );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
19
  add_filter( 'relevanssi_post_content', 'relevanssi_gutenberg_block_rendering', 10 );
20
 
21
  /**
22
+ * Renders Gutenberg blocks.
23
  *
24
+ * Renders all sorts of Gutenberg blocks, including reusable blocks and ACF
25
+ * blocks. Also enables basic Gutenberg deindexing: you can add an extra CSS
26
+ * class 'relevanssi_noindex' to a block to stop it from being indexed by
27
+ * Relevanssi. This function is essentially the same as core do_blocks().
28
+ *
29
+ * @see do_blocks()
30
  *
31
  * @param string $content The post content.
32
  *
33
  * @return string The post content with the rendered content added.
34
  */
35
  function relevanssi_gutenberg_block_rendering( $content ) {
36
+ $blocks = parse_blocks( $content );
37
+ $output = '';
38
+
39
+ foreach ( $blocks as $block ) {
40
+ if ( ! isset( $block['attrs']['className'] ) || strstr( $block['attrs']['className'], 'relevanssi_noindex' ) === false ) {
41
+ $output .= render_block( $block );
42
+ }
43
+ }
44
+
45
+ // If there are blocks in this content, we shouldn't run wpautop() on it later.
46
+ $priority = has_filter( 'the_content', 'wpautop' );
47
+ if ( false !== $priority && doing_filter( 'the_content' ) && has_blocks( $content ) ) {
48
+ remove_filter( 'the_content', 'wpautop', $priority );
49
+ add_filter( 'the_content', '_restore_wpautop_hook', $priority + 1 );
50
+ }
51
+
52
+ return $output;
53
  }
lib/compatibility/ninjatables.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * /lib/compatibility/ninjatables.php
4
+ *
5
+ * Ninja Tables compatibility features.
6
+ *
7
+ * @package Relevanssi
8
+ * @author Mikko Saari
9
+ * @license https://wordpress.org/about/gpl/ GNU General Public License
10
+ * @see https://www.relevanssi.com/
11
+ */
12
+
13
+ add_filter( 'relevanssi_post_content', 'relevanssi_index_ninja_tables' );
14
+
15
+ /**
16
+ * Indexes Ninja Tables table contents.
17
+ *
18
+ * Uses regular expression matching to find all the Ninja Tables shortcodes in
19
+ * the post content and then uses relevanssi_index_ninja_table() to convert the
20
+ * tables into strings.
21
+ *
22
+ * @uses $wpdb WordPress database abstraction.
23
+ * @see relevanssi_index_ninja_table()
24
+ *
25
+ * @param string $content The post content.
26
+ *
27
+ * @return string Post content with the Ninja Tables data.
28
+ */
29
+ function relevanssi_index_ninja_tables( $content ) {
30
+ $m = preg_match_all(
31
+ '/.*\[ninja_tables.*?id=["\'](\d+)["\'].*?\]/im',
32
+ $content,
33
+ $matches,
34
+ PREG_PATTERN_ORDER
35
+ );
36
+ if ( ! $m ) {
37
+ return $content;
38
+ }
39
+ foreach ( $matches[1] as $table_id ) {
40
+ $content .= ' ' . relevanssi_index_ninja_table( $table_id );
41
+ }
42
+
43
+ return $content;
44
+ }
45
+
46
+ /**
47
+ * Creates a string containing a Ninja Table table contents.
48
+ *
49
+ * The string contains the caption and the values from each row. The table
50
+ * title and description are also included, if they are set visible on the
51
+ * frontend.
52
+ *
53
+ * @uses $wpdb WordPress database abstraction.
54
+ *
55
+ * @param int $table_id The table ID.
56
+ *
57
+ * @return string The table content as a string.
58
+ */
59
+ function relevanssi_index_ninja_table( $table_id ) {
60
+ global $wpdb;
61
+ $table_post = get_post( $table_id );
62
+ $table_settings = get_post_meta( $table_id, '_ninja_table_settings', true );
63
+ $table_contents = '';
64
+
65
+ if ( isset( $table_settings['show_description'] ) && '1' === $table_settings['show_description'] ) {
66
+ $table_contents .= ' ' . $table_post->post_content;
67
+ }
68
+ if ( isset( $table_settings['show_title'] ) && '1' === $table_settings['show_title'] ) {
69
+ $table_contents .= ' ' . $table_post->post_title;
70
+ }
71
+ $table_contents .= ' ' . get_post_meta( $table_id, '_ninja_table_caption', true );
72
+
73
+ $rows = $wpdb->get_results(
74
+ $wpdb->prepare(
75
+ "SELECT value FROM {$wpdb->prefix}ninja_table_items WHERE table_id=%d",
76
+ $table_id
77
+ )
78
+ );
79
+ foreach ( $rows as $row ) {
80
+ $table_contents .= ' ' . implode( ' ', array_values( get_object_vars( json_decode( $row->value ) ) ) );
81
+ }
82
+
83
+ return $table_contents;
84
+ }
lib/compatibility/paidmembershippro.php CHANGED
@@ -22,8 +22,13 @@ add_filter( 'relevanssi_post_ok', 'relevanssi_paidmembershippro_compatibility',
22
  * otherwise false.
23
  */
24
  function relevanssi_paidmembershippro_compatibility( $post_ok, $post_id ) {
25
- $current_user = wp_get_current_user();
26
- $post_ok = pmpro_has_membership_access( $post_id, $current_user->ID );
 
 
 
 
 
27
 
28
  return $post_ok;
29
  }
22
  * otherwise false.
23
  */
24
  function relevanssi_paidmembershippro_compatibility( $post_ok, $post_id ) {
25
+ $status = relevanssi_get_post_status( $post_id );
26
+
27
+ if ( 'publish' === $status ) {
28
+ // Only apply to published posts, don't apply to drafts.
29
+ $current_user = wp_get_current_user();
30
+ $post_ok = pmpro_has_membership_access( $post_id, $current_user->ID );
31
+ }
32
 
33
  return $post_ok;
34
  }
lib/compatibility/polylang.php CHANGED
@@ -134,14 +134,26 @@ function relevanssi_polylang_term_filter( $hits ) {
134
  }
135
  $accepted_hits = array();
136
  foreach ( $hits[0] as $hit ) {
 
 
 
 
 
 
 
 
 
 
 
 
137
  if ( -1 === $hit->ID && isset( $hit->term_id ) ) {
138
  $term_id = intval( $hit->term_id );
139
  $translations = pll_get_term_translations( $term_id );
140
  if ( isset( $translations[ $current_language ] ) && $translations[ $current_language ] === $term_id ) {
141
- $accepted_hits[] = $hit;
142
  }
143
  } else {
144
- $accepted_hits[] = $hit;
145
  }
146
  }
147
  $hits[0] = $accepted_hits;
134
  }
135
  $accepted_hits = array();
136
  foreach ( $hits[0] as $hit ) {
137
+ $original_hit = $hit;
138
+ if ( is_numeric( $hit ) ) {
139
+ // In case "fields" is set to "ids", fetch the post object we need.
140
+ $original_hit = $hit;
141
+ $hit = get_post( $hit );
142
+ }
143
+ if ( ! isset( $hit->post_content ) ) {
144
+ // The "fields" is set to "id=>parent".
145
+ $original_hit = $hit;
146
+ $hit = get_post( $hit->ID );
147
+ }
148
+
149
  if ( -1 === $hit->ID && isset( $hit->term_id ) ) {
150
  $term_id = intval( $hit->term_id );
151
  $translations = pll_get_term_translations( $term_id );
152
  if ( isset( $translations[ $current_language ] ) && $translations[ $current_language ] === $term_id ) {
153
+ $accepted_hits[] = $original_hit;
154
  }
155
  } else {
156
+ $accepted_hits[] = $original_hit;
157
  }
158
  }
159
  $hits[0] = $accepted_hits;
lib/indexing.php CHANGED
@@ -129,12 +129,17 @@ function relevanssi_generate_indexing_query( $valid_status, $extend = false, $re
129
  AND post.ID NOT IN (SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_hide_post' AND meta_value = 'on')
130
  $restriction ORDER BY post.ID DESC $limit";
131
  } else {
 
 
 
 
 
132
  $q = "SELECT post.ID
133
  FROM $wpdb->posts post
134
  LEFT JOIN $wpdb->posts parent ON (post.post_parent=parent.ID)
135
  LEFT JOIN $relevanssi_table r ON (post.ID=r.doc)
136
  WHERE
137
- r.doc is null
138
  AND
139
  (post.post_status IN ($valid_status)
140
  OR
@@ -149,7 +154,12 @@ function relevanssi_generate_indexing_query( $valid_status, $extend = false, $re
149
  $restriction ORDER BY post.ID DESC $limit";
150
  }
151
 
152
- return $q;
 
 
 
 
 
153
  }
154
 
155
  /**
@@ -193,14 +203,20 @@ function relevanssi_post_type_restriction() {
193
  /**
194
  * Generates a list of valid post statuses.
195
  *
196
- * Generates a list of valid post statuses to use in indexing. By default, Relevanssi
197
- * accepts 'publish', 'draft', 'private', 'pending', and 'future'. If you need to use
198
- * a custom post status, you can use the 'relevanssi_valid_status' filter hook to add
199
- * your own post status to the list of valid statuses.
 
 
 
 
200
  *
201
- * @return string A comma-separated list of valid post statuses ready for MySQL.
 
 
202
  */
203
- function relevanssi_valid_status_array() {
204
  /**
205
  * Filters the valid status array.
206
  *
@@ -210,7 +226,12 @@ function relevanssi_valid_status_array() {
210
  * @return array Array of post statuses.
211
  */
212
  $valid_status_array = apply_filters( 'relevanssi_valid_status', array( 'publish', 'draft', 'private', 'pending', 'future' ) );
213
- $valid_status = array();
 
 
 
 
 
214
 
215
  if ( is_array( $valid_status_array ) && count( $valid_status_array ) > 0 ) {
216
  foreach ( $valid_status_array as $status ) {
@@ -229,21 +250,23 @@ function relevanssi_valid_status_array() {
229
  * Builds the index.
230
  *
231
  * @global object $wpdb The WordPress database interface.
232
- * @global array $relevanssi_variables The Relevanssi global variables array, used
233
- * for table names.
234
  *
235
  * @param boolean|int $extend_offset If numeric, offsets the indexing by that
236
- * amount. If true, doesn't truncate the index before indexing. If false, truncates
237
- * index before indexing. Default false.
238
- * @param boolean $verbose Not used anymore, kept for backwards compatibility.
239
- * @param int $post_limit How many posts to index. Default null, no limit.
 
 
240
  * @param boolean $is_ajax If true, indexing is done in AJAX context.
241
  * Default false.
242
  *
243
- * @return array In AJAX context, returns array with two values: 'indexing_complete'
244
- * tells whether indexing is completed or not, and 'indexed' returns the number of
245
- * posts indexed. Outside AJAX context, these values are returned as an array in
246
- * format of array(completed, posts indexed).
247
  */
248
  function relevanssi_build_index( $extend_offset = false, $verbose = null, $post_limit = null, $is_ajax = false ) {
249
  global $wpdb, $relevanssi_variables;
@@ -367,6 +390,9 @@ function relevanssi_build_index( $extend_offset = false, $verbose = null, $post_
367
  * Default false.
368
  * @param boolean $debug If true, echo out debugging information.
369
  * Default false.
 
 
 
370
  */
371
  function relevanssi_index_doc( $index_post, $remove_first = false, $custom_fields = '', $bypass_global_post = false, $debug = false ) {
372
  global $wpdb, $post, $relevanssi_variables;
@@ -706,16 +732,22 @@ function relevanssi_update_child_posts( $new_status, $old_status, $post ) {
706
  * Indexes a published post.
707
  *
708
  * @param int $post_id The post ID.
709
- * @param boolean $bypass_global_post If tru, bypass the global $post object. Default false.
 
 
 
 
 
 
710
  */
711
  function relevanssi_publish( $post_id, $bypass_global_post = false ) {
712
  $post_status = get_post_status( $post_id );
713
  if ( 'auto-draft' === $post_status ) {
714
- return;
715
  }
716
 
717
  $custom_fields = relevanssi_get_custom_fields();
718
- relevanssi_index_doc( $post_id, true, $custom_fields, $bypass_global_post );
719
  }
720
 
721
  /**
@@ -730,13 +762,19 @@ function relevanssi_publish( $post_id, $bypass_global_post = false ) {
730
  * @global object $wpdb The WP database interface.
731
  *
732
  * @param int $post_id The post ID.
 
 
 
 
 
 
733
  */
734
  function relevanssi_insert_edit( $post_id ) {
735
  global $wpdb;
736
 
737
  $post_status = get_post_status( $post_id );
738
  if ( 'auto-draft' === $post_status ) {
739
- return;
740
  }
741
 
742
  if ( 'inherit' === $post_status ) {
@@ -758,125 +796,76 @@ function relevanssi_insert_edit( $post_id ) {
758
  }
759
  }
760
 
761
- $index_statuses = apply_filters( 'relevanssi_valid_status', array( 'publish', 'private', 'draft', 'future', 'pending' ) );
 
762
  if ( ! in_array( $post_status, $index_statuses, true ) ) {
763
  $index_this_post = false;
764
  }
765
 
766
  if ( $index_this_post ) {
767
  $bypass_global_post = true;
768
- relevanssi_publish( $post_id, $bypass_global_post );
769
  } else {
770
  // The post isn't supposed to be indexed anymore, remove it from index.
771
  relevanssi_remove_doc( $post_id );
 
772
  }
773
 
774
  relevanssi_update_doc_count();
775
- }
776
 
777
- /**
778
- * Triggers comment indexing when a comment is edited.
779
- *
780
- * @author OdditY
781
- *
782
- * @param int $comment_id Comment id.
783
- */
784
- function relevanssi_comment_edit( $comment_id ) {
785
- $action = 'update';
786
- relevanssi_index_comment( $comment_id, $action );
787
  }
788
 
789
  /**
790
- * Triggers comment indexing when a comment is deleted.
791
  *
792
  * @author OdditY
793
  *
794
- * @param int $comment_id Comment ID.
795
- */
796
- function relevanssi_comment_remove( $comment_id ) {
797
- $action = 'remove';
798
- relevanssi_index_comment( $comment_id, $action );
799
- }
800
-
801
- /**
802
- * Updates comment indexing when comments are added, edited or deleted.
803
  *
804
- * @author OdditY
 
 
805
  *
806
- * @param int $comment_id Commend ID.
807
- * @param string $action What to do: 'add', 'update', 'remove'. Default 'add'.
 
808
  */
809
- function relevanssi_index_comment( $comment_id, $action = 'add' ) {
810
- global $wpdb;
811
-
812
  $comment_indexing_type = get_option( 'relevanssi_index_comments' );
813
  $no_pingbacks = false;
814
  $post_id = null;
815
 
816
- switch ( $comment_indexing_type ) {
817
- case 'all':
818
- // All.
819
- break;
820
- case 'normal':
821
- // Exclude trackbacks and pingbacks.
822
- $no_pingbacks = true;
823
- break;
824
- default:
825
- // No indexing.
826
- return;
827
  }
828
- switch ( $action ) {
829
- case 'update':
830
- // Update, reindex the post.
831
- $comment = get_comment( $comment_id );
832
- if ( $no_pingbacks && ! empty( $comment->comment_type ) ) {
833
- break;
834
- }
835
- $post_id = $comment->comment_post_ID;
836
- break;
837
- case 'remove':
838
- // Remove, empty the comment and reindex the post.
839
- $comment = get_comment( $comment_id );
840
- if ( $no_pingbacks && ! empty( $comment->comment_type ) ) {
841
- break;
842
- }
843
- $post_id = $comment->comment_post_ID;
844
- if ( $post_id ) {
845
- // Empty comment_content and reindex, then let WP delete the empty comment.
846
- $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->comments SET comment_content='' WHERE comment_ID=%d", $comment_id ) );
847
- }
848
- break;
849
- default:
850
- // Add new comment.
851
- $comment = get_comment( $comment_id );
852
- if ( $no_pingbacks && ! empty( $comment->comment_type ) ) {
853
- break;
854
- }
855
- if ( 1 !== intval( $comment->comment_approved ) ) {
856
- // Comment isn't approved, do not index.
857
- break;
858
- }
859
- $post_id = $comment->comment_post_ID;
860
- break;
861
  }
862
- if ( $post_id ) {
863
- relevanssi_publish( $post_id );
864
  }
 
 
 
 
 
865
  }
866
 
867
  /**
868
  * Returns the comment text for a post.
869
  *
870
- * @global object $wpdb The WordPress database interface.
871
- *
872
  * @param int $post_id The post ID.
873
  *
874
  * @return string All the comment content as a string that has the comment author
875
  * and the comment text.
876
  */
877
  function relevanssi_get_comments( $post_id ) {
878
- global $wpdb;
879
-
880
  /**
881
  * If this filter returns true, the comments for the post are not indexed.
882
  *
@@ -909,7 +898,6 @@ function relevanssi_get_comments( $post_id ) {
909
  'type' => $comment_types,
910
  );
911
  $comments = get_approved_comments( $post_id, $args );
912
-
913
  if ( count( $comments ) === 0 ) {
914
  break;
915
  }
129
  AND post.ID NOT IN (SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_relevanssi_hide_post' AND meta_value = 'on')
130
  $restriction ORDER BY post.ID DESC $limit";
131
  } else {
132
+ $processed_post_filter = 'r.doc is null';
133
+ if ( 'noindex' !== get_option( 'relevanssi_internal_links', 'noindex' ) ) {
134
+ $processed_post_filter = "(r.doc is null OR r.doc NOT IN (SELECT DISTINCT(doc) FROM $relevanssi_table WHERE link = 0))";
135
+ }
136
+
137
  $q = "SELECT post.ID
138
  FROM $wpdb->posts post
139
  LEFT JOIN $wpdb->posts parent ON (post.post_parent=parent.ID)
140
  LEFT JOIN $relevanssi_table r ON (post.ID=r.doc)
141
  WHERE
142
+ $processed_post_filter
143
  AND
144
  (post.post_status IN ($valid_status)
145
  OR
154
  $restriction ORDER BY post.ID DESC $limit";
155
  }
156
 
157
+ /**
158
+ * Filters the Relevanssi indexing query.
159
+ *
160
+ * @param string $q The indexing MySQL query.
161
+ */
162
+ return apply_filters( 'relevanssi_indexing_query', $q );
163
  }
164
 
165
  /**
203
  /**
204
  * Generates a list of valid post statuses.
205
  *
206
+ * Generates a list of valid post statuses to use in indexing. By default,
207
+ * Relevanssi accepts 'publish', 'draft', 'private', 'pending', and 'future'. If
208
+ * you need to use a custom post status, you can use the
209
+ * 'relevanssi_valid_status' filter hook to add your own post status to the list
210
+ * of valid statuses.
211
+ *
212
+ * @param boolean $return_array If true, return array; default false, return
213
+ * string.
214
  *
215
+ * @return string|array A comma-separated list of escaped valid post statuses
216
+ * ready for MySQL, or an unfiltered array, depending on the $return_array
217
+ * parameter.
218
  */
219
+ function relevanssi_valid_status_array( $return_array = false ) {
220
  /**
221
  * Filters the valid status array.
222
  *
226
  * @return array Array of post statuses.
227
  */
228
  $valid_status_array = apply_filters( 'relevanssi_valid_status', array( 'publish', 'draft', 'private', 'pending', 'future' ) );
229
+
230
+ if ( $return_array ) {
231
+ return $valid_status_array;
232
+ }
233
+
234
+ $valid_status = array();
235
 
236
  if ( is_array( $valid_status_array ) && count( $valid_status_array ) > 0 ) {
237
  foreach ( $valid_status_array as $status ) {
250
  * Builds the index.
251
  *
252
  * @global object $wpdb The WordPress database interface.
253
+ * @global array $relevanssi_variables The Relevanssi global variables array,
254
+ * used for table names.
255
  *
256
  * @param boolean|int $extend_offset If numeric, offsets the indexing by that
257
+ * amount. If true, doesn't truncate the index before indexing. If false,
258
+ * truncates index before indexing. Default false.
259
+ * @param boolean $verbose Not used anymore, kept for backwards
260
+ * compatibility.
261
+ * @param int $post_limit How many posts to index. Default null, no
262
+ * limit.
263
  * @param boolean $is_ajax If true, indexing is done in AJAX context.
264
  * Default false.
265
  *
266
+ * @return array In AJAX context, returns array with two values:
267
+ * 'indexing_complete' tells whether indexing is completed or not, and 'indexed'
268
+ * returns the number of posts indexed. Outside AJAX context, these values are
269
+ * returned as an array in format of array(completed, posts indexed).
270
  */
271
  function relevanssi_build_index( $extend_offset = false, $verbose = null, $post_limit = null, $is_ajax = false ) {
272
  global $wpdb, $relevanssi_variables;
390
  * Default false.
391
  * @param boolean $debug If true, echo out debugging information.
392
  * Default false.
393
+ *
394
+ * @return string|int Number of insert queries run, or -1 if the indexing fails,
395
+ * or 'hide' in case the post is hidden or 'donotindex' if a filter blocks this.
396
  */
397
  function relevanssi_index_doc( $index_post, $remove_first = false, $custom_fields = '', $bypass_global_post = false, $debug = false ) {
398
  global $wpdb, $post, $relevanssi_variables;
732
  * Indexes a published post.
733
  *
734
  * @param int $post_id The post ID.
735
+ * @param boolean $bypass_global_post If true, bypass the global $post object.
736
+ * Default false.
737
+ *
738
+ * @return string|int Returns 'auto-draft' if the post is an auto draft and
739
+ * thus skipped, or the relevanssi_index_doc() return value.
740
+ *
741
+ * @see relevanssi_index_doc()
742
  */
743
  function relevanssi_publish( $post_id, $bypass_global_post = false ) {
744
  $post_status = get_post_status( $post_id );
745
  if ( 'auto-draft' === $post_status ) {
746
+ return 'auto-draft';
747
  }
748
 
749
  $custom_fields = relevanssi_get_custom_fields();
750
+ return relevanssi_index_doc( $post_id, true, $custom_fields, $bypass_global_post );
751
  }
752
 
753
  /**
762
  * @global object $wpdb The WP database interface.
763
  *
764
  * @param int $post_id The post ID.
765
+ *
766
+ * @return string|int Returns 'auto-draft' if the post is an auto draft and
767
+ * thus skipped, 'removed' if the post is removed or the relevanssi_index_doc()
768
+ * return value from relevanssi_publish().
769
+ *
770
+ * @see relevanssi_publish()
771
  */
772
  function relevanssi_insert_edit( $post_id ) {
773
  global $wpdb;
774
 
775
  $post_status = get_post_status( $post_id );
776
  if ( 'auto-draft' === $post_status ) {
777
+ return 'auto-draft';
778
  }
779
 
780
  if ( 'inherit' === $post_status ) {
796
  }
797
  }
798
 
799
+ $return_array = true;
800
+ $index_statuses = relevanssi_valid_status_array( $return_array );
801
  if ( ! in_array( $post_status, $index_statuses, true ) ) {
802
  $index_this_post = false;
803
  }
804
 
805
  if ( $index_this_post ) {
806
  $bypass_global_post = true;
807
+ $return_value = relevanssi_publish( $post_id, $bypass_global_post );
808
  } else {
809
  // The post isn't supposed to be indexed anymore, remove it from index.
810
  relevanssi_remove_doc( $post_id );
811
+ $return_value = 'removed';
812
  }
813
 
814
  relevanssi_update_doc_count();
 
815
 
816
+ return $return_value;
 
 
 
 
 
 
 
 
 
817
  }
818
 
819
  /**
820
+ * Updates comment indexing when comments are added, edited or deleted.
821
  *
822
  * @author OdditY
823
  *
824
+ * @param int $comment_id Commend ID.
 
 
 
 
 
 
 
 
825
  *
826
+ * @see relevanssi_comment_remove
827
+ * @see relevanssi_comment_edit
828
+ * @see relevanssi_publish
829
  *
830
+ * @return int|string The relevanssi_publish return value, "nocommentfound" if
831
+ * the comment doesn't exist or "donotindex" if it cannot be indexed.
832
+ * comment indexing is disabled.
833
  */
834
+ function relevanssi_index_comment( $comment_id ) {
 
 
835
  $comment_indexing_type = get_option( 'relevanssi_index_comments' );
836
  $no_pingbacks = false;
837
  $post_id = null;
838
 
839
+ if ( 'normal' === $comment_indexing_type ) {
840
+ $no_pingbacks = true;
 
 
 
 
 
 
 
 
 
841
  }
842
+ if ( 'normal' !== $comment_indexing_type && 'all' !== $comment_indexing_type ) {
843
+ return 'donotindex';
844
+ }
845
+
846
+ $comment = get_comment( $comment_id );
847
+ if ( ! $comment ) {
848
+ return 'nocommentfound';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
849
  }
850
+ if ( $no_pingbacks && ! empty( $comment->comment_type ) ) {
851
+ return 'donotindex';
852
  }
853
+ if ( 1 !== intval( $comment->comment_approved ) ) {
854
+ // Comment isn't approved, do not index.
855
+ return 'donotindex';
856
+ }
857
+ return relevanssi_publish( $comment->comment_post_ID );
858
  }
859
 
860
  /**
861
  * Returns the comment text for a post.
862
  *
 
 
863
  * @param int $post_id The post ID.
864
  *
865
  * @return string All the comment content as a string that has the comment author
866
  * and the comment text.
867
  */
868
  function relevanssi_get_comments( $post_id ) {
 
 
869
  /**
870
  * If this filter returns true, the comments for the post are not indexed.
871
  *
898
  'type' => $comment_types,
899
  );
900
  $comments = get_approved_comments( $post_id, $args );
 
901
  if ( count( $comments ) === 0 ) {
902
  break;
903
  }
lib/init.php CHANGED
@@ -26,8 +26,9 @@ add_action( 'delete_post', 'relevanssi_remove_doc' );
26
 
27
  // Comment indexing.
28
  add_action( 'comment_post', 'relevanssi_index_comment' );
29
- add_action( 'edit_comment', 'relevanssi_comment_edit' );
30
- add_action( 'delete_comment', 'relevanssi_comment_remove' );
 
31
 
32
  // Attachment indexing.
33
  add_action( 'delete_attachment', 'relevanssi_remove_doc' );
@@ -42,6 +43,7 @@ add_filter( 'relevanssi_remove_punctuation', 'relevanssi_remove_punct' );
42
  add_filter( 'relevanssi_post_ok', 'relevanssi_default_post_ok', 9, 2 );
43
  add_filter( 'relevanssi_query_filter', 'relevanssi_limit_filter' );
44
  add_action( 'relevanssi_trim_logs', 'relevanssi_trim_logs' );
 
45
 
46
  // Plugin and theme compatibility.
47
  add_filter( 'relevanssi_pre_excerpt_content', 'relevanssi_remove_page_builder_shortcodes', 9 );
@@ -194,6 +196,10 @@ function relevanssi_init() {
194
 
195
  // Always required, the functions check if TablePress is active.
196
  require_once 'compatibility/tablepress.php';
 
 
 
 
197
  }
198
 
199
  /**
26
 
27
  // Comment indexing.
28
  add_action( 'comment_post', 'relevanssi_index_comment' );
29
+ add_action( 'edit_comment', 'relevanssi_index_comment' );
30
+ add_action( 'trashed_comment', 'relevanssi_index_comment' );
31
+ add_action( 'deleted_comment', 'relevanssi_index_comment' );
32
 
33
  // Attachment indexing.
34
  add_action( 'delete_attachment', 'relevanssi_remove_doc' );
43
  add_filter( 'relevanssi_post_ok', 'relevanssi_default_post_ok', 9, 2 );
44
  add_filter( 'relevanssi_query_filter', 'relevanssi_limit_filter' );
45
  add_action( 'relevanssi_trim_logs', 'relevanssi_trim_logs' );
46
+ add_action( 'relevanssi_custom_field_value', 'relevanssi_filter_custom_fields', 10, 2 );
47
 
48
  // Plugin and theme compatibility.
49
  add_filter( 'relevanssi_pre_excerpt_content', 'relevanssi_remove_page_builder_shortcodes', 9 );
196
 
197
  // Always required, the functions check if TablePress is active.
198
  require_once 'compatibility/tablepress.php';
199
+
200
+ if ( defined( 'NINJA_TABLES_VERSION' ) ) {
201
+ require_once 'compatibility/ninjatables.php';
202
+ }
203
  }
204
 
205
  /**
lib/search-query-restrictions.php CHANGED
@@ -23,9 +23,11 @@ function relevanssi_process_query_args( $args ) {
23
  $query_restrictions = '';
24
  $query_join = '';
25
  $query = '';
 
26
 
27
  if ( function_exists( 'wp_encode_emoji' ) ) {
28
- $query = wp_encode_emoji( $args['q'] );
 
29
  }
30
 
31
  if ( $args['sentence'] ) {
@@ -89,6 +91,7 @@ function relevanssi_process_query_args( $args ) {
89
  'query_restrictions' => $query_restrictions,
90
  'query_join' => $query_join,
91
  'query_query' => $query,
 
92
  );
93
  }
94
 
23
  $query_restrictions = '';
24
  $query_join = '';
25
  $query = '';
26
+ $query_no_synonyms = '';
27
 
28
  if ( function_exists( 'wp_encode_emoji' ) ) {
29
+ $query = wp_encode_emoji( $args['q'] );
30
+ $query_no_synonyms = wp_encode_emoji( $args['q_no_synonyms'] );
31
  }
32
 
33
  if ( $args['sentence'] ) {
91
  'query_restrictions' => $query_restrictions,
92
  'query_join' => $query_join,
93
  'query_query' => $query,
94
+ 'query_no_synonyms' => $query_no_synonyms,
95
  );
96
  }
97
 
lib/search.php CHANGED
@@ -129,6 +129,7 @@ function relevanssi_search( $args ) {
129
  $query_restrictions = $query_data['query_restrictions'];
130
  $query_join = $query_data['query_join'];
131
  $q = $query_data['query_query'];
 
132
 
133
  /**
134
  * Filters whether stopwords are removed from titles.
@@ -180,15 +181,19 @@ function relevanssi_search( $args ) {
180
 
181
  $total_hits = 0;
182
 
183
- $title_matches = array();
184
- $tag_matches = array();
185
- $comment_matches = array();
186
- $link_matches = array();
187
- $body_matches = array();
188
- $category_matches = array();
189
- $taxonomy_matches = array();
190
- $scores = array();
191
- $term_hits = array();
 
 
 
 
192
 
193
  $fuzzy = get_option( 'relevanssi_fuzzy' );
194
 
@@ -470,7 +475,7 @@ function relevanssi_search( $args ) {
470
 
471
  if ( $exact_match_bonus ) {
472
  $post = relevanssi_get_post( $match->doc );
473
- $clean_q = str_replace( array( '"', '”', '“' ), '', $q );
474
  if ( $post && $clean_q ) {
475
  if ( stristr( $post->post_title, $clean_q ) !== false ) {
476
  $match->weight *= $exact_match_boost['title'];
@@ -502,13 +507,29 @@ function relevanssi_search( $args ) {
502
  if ( ! isset( $comment_matches[ $match->doc ] ) ) {
503
  $comment_matches[ $match->doc ] = 0;
504
  }
505
- $body_matches[ $match->doc ] += $match->content;
506
- $title_matches[ $match->doc ] += $match->title;
507
- $link_matches[ $match->doc ] += $match->link;
508
- $tag_matches[ $match->doc ] += $match->tag;
509
- $category_matches[ $match->doc ] += $match->category;
510
- $taxonomy_matches[ $match->doc ] += $match->taxonomy;
511
- $comment_matches[ $match->doc ] += $match->comment;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
512
 
513
  /* Post type weights. */
514
  $type = null;
@@ -668,19 +689,24 @@ function relevanssi_search( $args ) {
668
  global $wp_query;
669
  $wp_query->set( 'operator', 'OR' );
670
 
671
- $or_args['q'] = relevanssi_add_synonyms( $q );
672
- $return = relevanssi_search( $or_args );
673
-
674
- $hits = $return['hits'];
675
- $body_matches = $return['body_matches'];
676
- $title_matches = $return['title_matches'];
677
- $tag_matches = $return['tag_matches'];
678
- $category_matches = $return['category_matches'];
679
- $taxonomy_matches = $return['taxonomy_matches'];
680
- $comment_matches = $return['comment_matches'];
681
- $link_matches = $return['link_matches'];
682
- $term_hits = $return['term_hits'];
683
- $q = $return['query'];
 
 
 
 
 
684
  }
685
  $params = array( 'args' => $args );
686
  /**
@@ -695,18 +721,21 @@ function relevanssi_search( $args ) {
695
  $params = apply_filters( 'relevanssi_fallback', $params );
696
  $args = $params['args'];
697
  if ( isset( $params['return'] ) ) {
698
- $return = $params['return'];
699
- $hits = $return['hits'];
700
- $body_matches = $return['body_matches'];
701
- $title_matches = $return['title_matches'];
702
- $tag_matches = $return['tag_matches'];
703
- $category_matches = $return['category_matches'];
704
- $taxonomy_matches = $return['taxonomy_matches'];
705
- $comment_matches = $return['comment_matches'];
706
- $body_matches = $return['body_matches'];
707
- $link_matches = $return['link_matches'];
708
- $term_hits = $return['term_hits'];
709
- $q = $return['query'];
 
 
 
710
  }
711
  }
712
 
@@ -753,17 +782,21 @@ function relevanssi_search( $args ) {
753
  }
754
  }
755
  $return = array(
756
- 'hits' => $hits,
757
- 'body_matches' => $body_matches,
758
- 'title_matches' => $title_matches,
759
- 'tag_matches' => $tag_matches,
760
- 'category_matches' => $category_matches,
761
- 'taxonomy_matches' => $taxonomy_matches,
762
- 'comment_matches' => $comment_matches,
763
- 'scores' => $scores,
764
- 'term_hits' => $term_hits,
765
- 'query' => $q,
766
- 'link_matches' => $link_matches,
 
 
 
 
767
  );
768
 
769
  return $return;
@@ -920,6 +953,9 @@ function relevanssi_do_query( &$query ) {
920
  restore_current_blog();
921
  }
922
  }
 
 
 
923
  if ( 'on' === get_option( 'relevanssi_show_matches' ) && empty( $search_params['fields'] ) ) {
924
  $post_id = $post->ID;
925
  if ( 'user' === $post->post_type ) {
@@ -932,7 +968,7 @@ function relevanssi_do_query( &$query ) {
932
  if ( isset( $post->blog_id ) ) {
933
  $post_id = $post->blog_id . '|' . $post->ID;
934
  }
935
- $post->post_excerpt .= relevanssi_show_matches( $return, $post_id );
936
  }
937
 
938
  if ( empty( $search_params['fields'] ) ) {
@@ -1245,8 +1281,6 @@ function relevanssi_compile_search_args( $query, $q ) {
1245
  'operator' => 'NOT IN',
1246
  );
1247
  }
1248
-
1249
- $query->tax_query = $tax_query;
1250
  }
1251
 
1252
  $author = false;
@@ -1456,8 +1490,13 @@ function relevanssi_compile_search_args( $query, $q ) {
1456
  $include_attachments = $query->query_vars['include_attachments'];
1457
  }
1458
 
 
 
 
 
1459
  // Add synonyms.
1460
  // This is done here so the new terms will get highlighting.
 
1461
  if ( 'OR' === $operator ) {
1462
  // Synonyms are only used in OR queries.
1463
  $q = relevanssi_add_synonyms( $q );
@@ -1465,6 +1504,7 @@ function relevanssi_compile_search_args( $query, $q ) {
1465
 
1466
  $search_params = array(
1467
  'q' => $q,
 
1468
  'tax_query' => $tax_query,
1469
  'tax_query_relation' => $tax_query_relation,
1470
  'post_query' => $post_query,
129
  $query_restrictions = $query_data['query_restrictions'];
130
  $query_join = $query_data['query_join'];
131
  $q = $query_data['query_query'];
132
+ $q_no_synonyms = $query_data['query_no_synonyms'];
133
 
134
  /**
135
  * Filters whether stopwords are removed from titles.
181
 
182
  $total_hits = 0;
183
 
184
+ $title_matches = array();
185
+ $tag_matches = array();
186
+ $comment_matches = array();
187
+ $link_matches = array();
188
+ $body_matches = array();
189
+ $category_matches = array();
190
+ $taxonomy_matches = array();
191
+ $customfield_matches = array();
192
+ $mysqlcolumn_matches = array();
193
+ $author_matches = array();
194
+ $excerpt_matches = array();
195
+ $scores = array();
196
+ $term_hits = array();
197
 
198
  $fuzzy = get_option( 'relevanssi_fuzzy' );
199
 
475
 
476
  if ( $exact_match_bonus ) {
477
  $post = relevanssi_get_post( $match->doc );
478
+ $clean_q = str_replace( array( '"', '”', '“' ), '', $q_no_synonyms );
479
  if ( $post && $clean_q ) {
480
  if ( stristr( $post->post_title, $clean_q ) !== false ) {
481
  $match->weight *= $exact_match_boost['title'];
507
  if ( ! isset( $comment_matches[ $match->doc ] ) ) {
508
  $comment_matches[ $match->doc ] = 0;
509
  }
510
+ if ( ! isset( $customfield_matches[ $match->doc ] ) ) {
511
+ $customfield_matches[ $match->doc ] = 0;
512
+ }
513
+ if ( ! isset( $author_matches[ $match->doc ] ) ) {
514
+ $author_matches[ $match->doc ] = 0;
515
+ }
516
+ if ( ! isset( $excerpt_matches[ $match->doc ] ) ) {
517
+ $excerpt_matches[ $match->doc ] = 0;
518
+ }
519
+ if ( ! isset( $mysqlcolumn_matches[ $match->doc ] ) ) {
520
+ $mysqlcolumn_matches[ $match->doc ] = 0;
521
+ }
522
+ $body_matches[ $match->doc ] += $match->content;
523
+ $title_matches[ $match->doc ] += $match->title;
524
+ $link_matches[ $match->doc ] += $match->link;
525
+ $tag_matches[ $match->doc ] += $match->tag;
526
+ $category_matches[ $match->doc ] += $match->category;
527
+ $taxonomy_matches[ $match->doc ] += $match->taxonomy;
528
+ $comment_matches[ $match->doc ] += $match->comment;
529
+ $customfield_matches[ $match->doc ] += $match->customfield;
530
+ $author_matches[ $match->doc ] += $match->author;
531
+ $excerpt_matches[ $match->doc ] += $match->excerpt;
532
+ $mysqlcolumn_matches[ $match->doc ] += $match->mysqlcolumn;
533
 
534
  /* Post type weights. */
535
  $type = null;
689
  global $wp_query;
690
  $wp_query->set( 'operator', 'OR' );
691
 
692
+ $or_args['q_no_synonyms'] = $q;
693
+ $or_args['q'] = relevanssi_add_synonyms( $q );
694
+ $return = relevanssi_search( $or_args );
695
+
696
+ $hits = $return['hits'];
697
+ $body_matches = $return['body_matches'];
698
+ $title_matches = $return['title_matches'];
699
+ $tag_matches = $return['tag_matches'];
700
+ $category_matches = $return['category_matches'];
701
+ $taxonomy_matches = $return['taxonomy_matches'];
702
+ $comment_matches = $return['comment_matches'];
703
+ $link_matches = $return['link_matches'];
704
+ $author_matches = $return['author_matches'];
705
+ $customfield_matches = $return['customfield_matches'];
706
+ $mysqlcolumn_matches = $return['mysqlcolumn_matches'];
707
+ $excerpt_matches = $return['excerpt_matches'];
708
+ $term_hits = $return['term_hits'];
709
+ $q = $return['query'];
710
  }
711
  $params = array( 'args' => $args );
712
  /**
721
  $params = apply_filters( 'relevanssi_fallback', $params );
722
  $args = $params['args'];
723
  if ( isset( $params['return'] ) ) {
724
+ $return = $params['return'];
725
+ $hits = $return['hits'];
726
+ $body_matches = $return['body_matches'];
727
+ $title_matches = $return['title_matches'];
728
+ $tag_matches = $return['tag_matches'];
729
+ $category_matches = $return['category_matches'];
730
+ $taxonomy_matches = $return['taxonomy_matches'];
731
+ $comment_matches = $return['comment_matches'];
732
+ $link_matches = $return['link_matches'];
733
+ $author_matches = $return['author_matches'];
734
+ $customfield_matches = $return['customfield_matches'];
735
+ $mysqlcolumn_matches = $return['mysqlcolumn_matches'];
736
+ $excerpt_matches = $return['excerpt_matches'];
737
+ $term_hits = $return['term_hits'];
738
+ $q = $return['query'];
739
  }
740
  }
741
 
782
  }
783
  }
784
  $return = array(
785
+ 'hits' => $hits,
786
+ 'body_matches' => $body_matches,
787
+ 'title_matches' => $title_matches,
788
+ 'tag_matches' => $tag_matches,
789
+ 'category_matches' => $category_matches,
790
+ 'comment_matches' => $comment_matches,
791
+ 'taxonomy_matches' => $taxonomy_matches,
792
+ 'link_matches' => $link_matches,
793
+ 'customfield_matches' => $customfield_matches,
794
+ 'mysqlcolumn_matches' => $mysqlcolumn_matches,
795
+ 'author_matches' => $author_matches,
796
+ 'excerpt_matches' => $excerpt_matches,
797
+ 'scores' => $scores,
798
+ 'term_hits' => $term_hits,
799
+ 'query' => $q,
800
  );
801
 
802
  return $return;
953
  restore_current_blog();
954
  }
955
  }
956
+ if ( empty( $search_params['fields'] ) ) {
957
+ relevanssi_add_matches( $post, $return );
958
+ }
959
  if ( 'on' === get_option( 'relevanssi_show_matches' ) && empty( $search_params['fields'] ) ) {
960
  $post_id = $post->ID;
961
  if ( 'user' === $post->post_type ) {
968
  if ( isset( $post->blog_id ) ) {
969
  $post_id = $post->blog_id . '|' . $post->ID;
970
  }
971
+ $post->post_excerpt .= relevanssi_show_matches( $post );
972
  }
973
 
974
  if ( empty( $search_params['fields'] ) ) {
1281
  'operator' => 'NOT IN',
1282
  );
1283
  }
 
 
1284
  }
1285
 
1286
  $author = false;
1490
  $include_attachments = $query->query_vars['include_attachments'];
1491
  }
1492
 
1493
+ if ( function_exists( 'relevanssi_extract_specifier' ) ) {
1494
+ $q = relevanssi_extract_specifier( $q );
1495
+ }
1496
+
1497
  // Add synonyms.
1498
  // This is done here so the new terms will get highlighting.
1499
+ $q_no_synonyms = $q;
1500
  if ( 'OR' === $operator ) {
1501
  // Synonyms are only used in OR queries.
1502
  $q = relevanssi_add_synonyms( $q );
1504
 
1505
  $search_params = array(
1506
  'q' => $q,
1507
+ 'q_no_synonyms' => $q_no_synonyms,
1508
  'tax_query' => $tax_query,
1509
  'tax_query_relation' => $tax_query_relation,
1510
  'post_query' => $post_query,
lib/tabs/excerpts-tab.php CHANGED
@@ -434,7 +434,7 @@ function relevanssi_excerpts_tab() {
434
  }
435
  ?>
436
  ><?php echo esc_attr( $show_matches_text ); ?></textarea>
437
- <p class="description"><?php esc_html_e( 'Use %body%, %title%, %tags% and %comments% to display the number of hits (in different parts of the post), %total% for total hits, %score% to display the document weight and %terms% to show how many hits each search term got.', 'relevanssi' ); /* phpcs:ignore WordPress.WP.I18n */ ?></p>
438
  </td>
439
  </tr>
440
  </table>
434
  }
435
  ?>
436
  ><?php echo esc_attr( $show_matches_text ); ?></textarea>
437
+ <p class="description"><?php esc_html_e( 'Use %body%, %title%, %categories%, %tags%, %taxonomies%, %comments%, %customfields%, %author%, %excerpt% and %mysqlcolumns% to display the number of hits (in different parts of the post), %total% for total hits, %score% to display the document weight and %terms% to show how many hits each search term got.', 'relevanssi' ); /* phpcs:ignore WordPress.WP.I18n */ ?></p>
438
  </td>
439
  </tr>
440
  </table>
readme.txt CHANGED
@@ -2,10 +2,10 @@
2
  Contributors: msaari
3
  Donate link: https://www.relevanssi.com/buy-premium/
4
  Tags: search, relevance, better search
5
- Requires at least: 4.8.3
6
- Tested up to: 5.2.3
7
  Requires PHP: 5.6
8
- Stable tag: 4.3.3
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -29,6 +29,7 @@ Do note that using Relevanssi may require large amounts (hundreds of megabytes)
29
  * Search comments, tags, categories and custom fields.
30
  * Multisite friendly.
31
  * bbPress support.
 
32
 
33
  = Advanced features =
34
  * Adjust the weighting for titles, tags and comments.
@@ -38,7 +39,7 @@ Do note that using Relevanssi may require large amounts (hundreds of megabytes)
38
  * Index the contents of shortcodes.
39
  * Google-style "Did you mean?" suggestions based on successful user searches.
40
  * Support for [WPML multi-language plugin](http://wpml.org/) and [Polylang](https://wordpress.org/plugins/polylang/).
41
- * Support for [s2member membership plugin](http://www.s2member.com/), [Members](https://wordpress.org/plugins/members/), [Groups](https://wordpress.org/plugins/groups/) and [Simple Membership](https://wordpress.org/plugins/simple-membership/).
42
  * Advanced filtering to help hacking the search results the way you want.
43
  * Search result throttling to improve performance on large databases.
44
  * Disable indexing of post content and post titles with a simple filter hook.
@@ -55,7 +56,8 @@ Do note that using Relevanssi may require large amounts (hundreds of megabytes)
55
  * Let the user choose between AND and OR searches, use + and - operator (AND and NOT).
56
  * Export and import settings.
57
  * [WP CLI commands](https://www.relevanssi.com/user-manual/wp-cli/).
58
- * Related posts.
 
59
 
60
  = Relevanssi in Facebook =
61
  You can find [Relevanssi in Facebook](https://www.facebook.com/relevanssi).
@@ -121,6 +123,8 @@ Thus, the weight of the word for a document increases the more often it appears
121
 
122
  Each document database is full of useless words. All the little words that appear in just about every document are completely useless for information retrieval purposes. Basically, their inverted document frequency is really low, so they never have much power in matching. Also, removing those words helps to make the index smaller and searching faster.
123
 
 
 
124
  == Thanks ==
125
  * Cristian Damm for tag indexing, comment indexing, post/page exclusion and general helpfulness.
126
  * Marcus Dalgren for UTF-8 fixing.
@@ -129,6 +133,18 @@ Each document database is full of useless words. All the little words that appea
129
  * John Calahan for extensive 4.0 beta testing.
130
 
131
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
132
  = 4.3.3 =
133
  * New feature: New filter hook `relevanssi_indexing_adjust` can be used to stop Relevanssi from adjusting the number of posts indexed at once during the indexing.
134
  * New feature: New filter hook `relevanssi_acf_field_value` filters ACF field values before they are indexed.
@@ -171,6 +187,9 @@ Each document database is full of useless words. All the little words that appea
171
  * Deprecated: `relevanssi_get_term_taxonomy()` function is deprecated and will be removed at some point in the future.
172
 
173
  == Upgrade notice ==
 
 
 
174
  = 4.3.3 =
175
  * Bug fixes and overall improvements.
176
 
2
  Contributors: msaari
3
  Donate link: https://www.relevanssi.com/buy-premium/
4
  Tags: search, relevance, better search
5
+ Requires at least: 4.9
6
+ Tested up to: 5.3
7
  Requires PHP: 5.6
8
+ Stable tag: 4.3.4
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
29
  * Search comments, tags, categories and custom fields.
30
  * Multisite friendly.
31
  * bbPress support.
32
+ * Gutenberg friendly.
33
 
34
  = Advanced features =
35
  * Adjust the weighting for titles, tags and comments.
39
  * Index the contents of shortcodes.
40
  * Google-style "Did you mean?" suggestions based on successful user searches.
41
  * Support for [WPML multi-language plugin](http://wpml.org/) and [Polylang](https://wordpress.org/plugins/polylang/).
42
+ * Support for [s2member membership plugin](http://www.s2member.com/), [Members](https://wordpress.org/plugins/members/), [Groups](https://wordpress.org/plugins/groups/), [Simple Membership](https://wordpress.org/plugins/simple-membership/) and other membership plugins.
43
  * Advanced filtering to help hacking the search results the way you want.
44
  * Search result throttling to improve performance on large databases.
45
  * Disable indexing of post content and post titles with a simple filter hook.
56
  * Let the user choose between AND and OR searches, use + and - operator (AND and NOT).
57
  * Export and import settings.
58
  * [WP CLI commands](https://www.relevanssi.com/user-manual/wp-cli/).
59
+ * [Related posts](https://www.relevanssi.com/knowledge-base/related-posts/).
60
+ * [Redirects for searches](https://www.relevanssi.com/user-manual/redirects/).
61
 
62
  = Relevanssi in Facebook =
63
  You can find [Relevanssi in Facebook](https://www.facebook.com/relevanssi).
123
 
124
  Each document database is full of useless words. All the little words that appear in just about every document are completely useless for information retrieval purposes. Basically, their inverted document frequency is really low, so they never have much power in matching. Also, removing those words helps to make the index smaller and searching faster.
125
 
126
+ [](http://coderisk.com/wp/plugin/relevanssi/RIPS-XC1ekC4JKr)
127
+
128
  == Thanks ==
129
  * Cristian Damm for tag indexing, comment indexing, post/page exclusion and general helpfulness.
130
  * Marcus Dalgren for UTF-8 fixing.
133
  * John Calahan for extensive 4.0 beta testing.
134
 
135
  == Changelog ==
136
+ = 4.3.4 =
137
+ * New feature: You can now give Gutenberg blocks a CSS class `relevanssi_noindex` to exclude them from being indexed. Relevanssi will not index Gutenberg blocks that have the class.
138
+ * New feature: Relevanssi automatically skips some custom fields from common plugins that only contain unnecessary metadata.
139
+ * New feature: The search results breakdown is added to the post objects and can be found in $post->relevanssi_hits. The data also includes new fields and the breakdown from the excerpt settings page can now show author, excerpt, custom field and MySQL column hits.
140
+ * New feature: Relevanssi can now index Ninja Tables table content. This is something of an experimental feature right now, feedback is welcome.
141
+ * New feature: New filter hook `relevanssi_indexing_query` filters the indexing query and is mostly interesting for debugging reasons.
142
+ * Minor fix: Deleted and trashed comment contents were not deindexed when the comment was removed. That has been corrected now.
143
+ * Minor fix: Phrase matching is now applied to attachments as well, including the attachments indexed for parent post.
144
+ * Minor fix: Phrase matching only looks at custom fields that are indexed by Relevanssi.
145
+ * Minor fix: Exact match bonus now uses the original query without synonyms added for the exact match check.
146
+ * Minor fix: Paid Membership Pro filtering is only applied to published posts to prevent drafts from showing up in the search results.
147
+
148
  = 4.3.3 =
149
  * New feature: New filter hook `relevanssi_indexing_adjust` can be used to stop Relevanssi from adjusting the number of posts indexed at once during the indexing.
150
  * New feature: New filter hook `relevanssi_acf_field_value` filters ACF field values before they are indexed.
187
  * Deprecated: `relevanssi_get_term_taxonomy()` function is deprecated and will be removed at some point in the future.
188
 
189
  == Upgrade notice ==
190
+ = 4.3.4 =
191
+ * Comment indexing bug fix, compatibility improvements and minor bug fixes and improvements.
192
+
193
  = 4.3.3 =
194
  * Bug fixes and overall improvements.
195
 
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.3.3
17
  * Author: Mikko Saari
18
  * Author URI: http://www.mikkosaari.fi/
19
  * Text Domain: relevanssi
@@ -41,6 +41,13 @@ define( 'RELEVANSSI_PREMIUM', false );
41
 
42
  add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'relevanssi_action_links' );
43
 
 
 
 
 
 
 
 
44
  global $relevanssi_variables;
45
  global $wpdb;
46
 
@@ -58,7 +65,7 @@ $relevanssi_variables['database_version'] = 5;
58
  $relevanssi_variables['file'] = __FILE__;
59
  $relevanssi_variables['plugin_dir'] = plugin_dir_path( __FILE__ );
60
  $relevanssi_variables['plugin_basename'] = plugin_basename( __FILE__ );
61
- $relevanssi_variables['plugin_version'] = '4.3.3';
62
 
63
  require_once 'lib/admin-ajax.php';
64
  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.3.4
17
  * Author: Mikko Saari
18
  * Author URI: http://www.mikkosaari.fi/
19
  * Text Domain: relevanssi
41
 
42
  add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'relevanssi_action_links' );
43
 
44
+ global $wp_version;
45
+ if ( version_compare( $wp_version, '5.1', '>=' ) ) {
46
+ add_action( 'wp_insert_site', 'relevanssi_new_blog', 10, 1 );
47
+ } else {
48
+ add_action( 'wpmu_new_blog', 'relevanssi_new_blog', 10, 1 );
49
+ }
50
+
51
  global $relevanssi_variables;
52
  global $wpdb;
53
 
65
  $relevanssi_variables['file'] = __FILE__;
66
  $relevanssi_variables['plugin_dir'] = plugin_dir_path( __FILE__ );
67
  $relevanssi_variables['plugin_basename'] = plugin_basename( __FILE__ );
68
+ $relevanssi_variables['plugin_version'] = '4.3.4';
69
 
70
  require_once 'lib/admin-ajax.php';
71
  require_once 'lib/common.php';