Relevanssi – A Better Search - Version 4.4.1

Version Description

  • Major fix: Returns the missing stopwords.
Download this release

Release Info

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

Code changes from version 4.3.4 to 4.4.1

lib/admin_scripts.js CHANGED
@@ -66,6 +66,13 @@ jQuery(document).ready(function($) {
66
  if (this.value != "some") fields_content.hide()
67
  })
68
 
 
 
 
 
 
 
 
69
  $("#show_advanced_indexing").click(function(e) {
70
  $("#advanced_indexing").toggleClass("screen-reader-text")
71
  $("#hide_advanced_indexing").show()
66
  if (this.value != "some") fields_content.hide()
67
  })
68
 
69
+ var index_images = $("#row_index_image_files")
70
+ var index_attachments = $("#relevanssi_index_type_attachment")
71
+ index_attachments.click(function() {
72
+ if (this.checked) index_images.show()
73
+ if (!this.checked) index_images.hide()
74
+ })
75
+
76
  $("#show_advanced_indexing").click(function(e) {
77
  $("#advanced_indexing").toggleClass("screen-reader-text")
78
  $("#hide_advanced_indexing").show()
lib/admin_scripts_free.js CHANGED
@@ -41,6 +41,7 @@ jQuery(document).ready(function($) {
41
  offset: 0,
42
  total_seconds: 0,
43
  limit: relevanssi_params.indexing_limit,
 
44
  extend: false,
45
  security: nonce.indexing_nonce
46
  }
41
  offset: 0,
42
  total_seconds: 0,
43
  limit: relevanssi_params.indexing_limit,
44
+ adjust: relevanssi_params.indexing_adjust,
45
  extend: false,
46
  security: nonce.indexing_nonce
47
  }
lib/admin_styles.css CHANGED
@@ -1,5 +1,5 @@
1
  p.important {
2
- color: #dd3300;
3
  }
4
 
5
  table.form-table table.widefat th {
1
  p.important {
2
+ color: #992000;
3
  }
4
 
5
  table.form-table table.widefat th {
lib/common.php CHANGED
@@ -278,14 +278,17 @@ function relevanssi_populate_array( $matches ) {
278
  array_push( $ids, $match->doc );
279
  }
280
 
281
- $ids = array_keys( array_flip( $ids ) ); // Remove duplicate IDs.
282
- $ids = implode( ', ', $ids );
283
- $posts = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE id IN ( $ids )", OBJECT ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
284
-
285
- foreach ( $posts as $post ) {
286
- $relevanssi_post_array[ $post->ID ] = $post;
287
- $relevanssi_post_types[ $post->ID ] = $post->post_type;
288
- }
 
 
 
289
 
290
  // Re-enable caching.
291
  wp_suspend_cache_addition( false );
@@ -520,11 +523,8 @@ function relevanssi_get_custom_fields() {
520
  } elseif ( 'visible' === $custom_fields ) {
521
  return $custom_fields;
522
  } else {
523
- $custom_fields = explode( ',', $custom_fields );
524
- $count_custom_fields = count( $custom_fields );
525
- for ( $i = 0; $i < $count_custom_fields; $i++ ) {
526
- $custom_fields[ $i ] = trim( $custom_fields[ $i ] );
527
- }
528
  }
529
  } else {
530
  $custom_fields = false;
@@ -1296,7 +1296,6 @@ function relevanssi_switch_blog( $new_blog, $prev_blog ) {
1296
  }
1297
 
1298
  $relevanssi_variables['relevanssi_table'] = $wpdb->prefix . 'relevanssi';
1299
- $relevanssi_variables['stopword_table'] = $wpdb->prefix . 'relevanssi_stopwords';
1300
  $relevanssi_variables['log_table'] = $wpdb->prefix . 'relevanssi_log';
1301
  }
1302
 
@@ -1529,7 +1528,7 @@ function relevanssi_simple_generate_suggestion( $query ) {
1529
  $data = get_transient( 'relevanssi_didyoumean_query' );
1530
  if ( empty( $data ) ) {
1531
  $data = $wpdb->get_results( $q ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
1532
- set_transient( 'relevanssi_didyoumean_query', $data, 60 * 60 * 24 * 7 );
1533
  }
1534
 
1535
  $query = htmlspecialchars_decode( $query, ENT_QUOTES );
@@ -1749,6 +1748,8 @@ function relevanssi_get_forbidden_post_types() {
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.
@@ -1759,6 +1760,23 @@ function relevanssi_get_forbidden_post_types() {
1759
  'amn_wpforms', // WP Forms.
1760
  'wpforms_log', // WP Forms.
1761
  'dlm_download_version', // Download Monitor.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1762
  );
1763
  }
1764
 
@@ -1774,6 +1792,9 @@ function relevanssi_get_forbidden_taxonomies() {
1774
  'amp_validation_error', // AMP.
1775
  'product_visibility', // WooCommerce.
1776
  'wpforms_log_type', // WP Forms.
 
 
 
1777
  );
1778
  }
1779
 
@@ -1810,3 +1831,51 @@ function relevanssi_filter_custom_fields( $values, $field ) {
1810
  }
1811
  return $values;
1812
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  array_push( $ids, $match->doc );
279
  }
280
 
281
+ $ids = array_keys( array_flip( $ids ) ); // Remove duplicate IDs.
282
+ do {
283
+ $hundred_ids = array_splice( $ids, 0, 100 );
284
+ $id_list = implode( ', ', $hundred_ids );
285
+ $posts = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE id IN ( $id_list )", OBJECT ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
286
+
287
+ foreach ( $posts as $post ) {
288
+ $relevanssi_post_array[ $post->ID ] = $post;
289
+ $relevanssi_post_types[ $post->ID ] = $post->post_type;
290
+ }
291
+ } while ( $ids );
292
 
293
  // Re-enable caching.
294
  wp_suspend_cache_addition( false );
523
  } elseif ( 'visible' === $custom_fields ) {
524
  return $custom_fields;
525
  } else {
526
+ $custom_fields_raw = explode( ',', $custom_fields );
527
+ $custom_fields = array_filter( array_map( 'trim', $custom_fields_raw ) );
 
 
 
528
  }
529
  } else {
530
  $custom_fields = false;
1296
  }
1297
 
1298
  $relevanssi_variables['relevanssi_table'] = $wpdb->prefix . 'relevanssi';
 
1299
  $relevanssi_variables['log_table'] = $wpdb->prefix . 'relevanssi_log';
1300
  }
1301
 
1528
  $data = get_transient( 'relevanssi_didyoumean_query' );
1529
  if ( empty( $data ) ) {
1530
  $data = $wpdb->get_results( $q ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
1531
+ set_transient( 'relevanssi_didyoumean_query', $data, MONTH_IN_SECONDS );
1532
  }
1533
 
1534
  $query = htmlspecialchars_decode( $query, ENT_QUOTES );
1748
  'ninja-table', // Ninja Tables.
1749
  'shop_order', // WooCommerce.
1750
  'shop_order_refund', // WooCommerce.
1751
+ 'wc_order_status', // WooCommerce.
1752
+ 'wc_order_email', // WooCommerce.
1753
  'shop_webhook', // WooCommerce.
1754
  'et_theme_builder', // Divi.
1755
  'et_template', // Divi.
1760
  'amn_wpforms', // WP Forms.
1761
  'wpforms_log', // WP Forms.
1762
  'dlm_download_version', // Download Monitor.
1763
+ 'wpcf7_contact_form', // WP Contact Form 7.
1764
+ 'amn_exact-metrics', // Google Analytics Dashboard.
1765
+ 'edd_commission', // Easy Digital Downloads.
1766
+ 'edd_payment', // Easy Digital Downloads.
1767
+ 'edd_discount', // Easy Digital Downloads.
1768
+ 'eddpointslog', // Easy Digital Downloads.
1769
+ 'edd_log', // Easy Digital Downloads.
1770
+ 'edd-zapier-sub', // Easy Digital Downloads.
1771
+ 'pys_event', // Pixel Your Site.
1772
+ 'wp-types-group', // WP Types.
1773
+ 'wp-types-term-group', // WP Types.
1774
+ 'wp-types-user-group', // WP Types.
1775
+ 'vc_grid_item', // Visual Composer.
1776
+ 'bigcommerce_task', // BigCommerce.
1777
+ 'slides', // Qoda slides.
1778
+ 'carousels', // Qoda carousels.
1779
+
1780
  );
1781
  }
1782
 
1792
  'amp_validation_error', // AMP.
1793
  'product_visibility', // WooCommerce.
1794
  'wpforms_log_type', // WP Forms.
1795
+ 'amp_template', // AMP.
1796
+ 'edd_commission_status', // Easy Digital Downloads.
1797
+ 'edd_log_type', // Easy Digital Downloads.
1798
  );
1799
  }
1800
 
1831
  }
1832
  return $values;
1833
  }
1834
+
1835
+
1836
+ /**
1837
+ * Removes page builder short codes from content.
1838
+ *
1839
+ * Page builder shortcodes cause problems in excerpts and add junk to posts in
1840
+ * indexing. This function cleans them out.
1841
+ *
1842
+ * @param string $content The content to clean.
1843
+ *
1844
+ * @return string The content without page builder shortcodes.
1845
+ */
1846
+ function relevanssi_remove_page_builder_shortcodes( $content ) {
1847
+ $context = current_filter();
1848
+ /**
1849
+ * Filters the page builder shortcode.
1850
+ *
1851
+ * @param array An array of page builder shortcode regexes.
1852
+ * @param string Context, ie. the current filter hook, if you want your
1853
+ * changes to only count for indexing or for excerpts. In indexing, this
1854
+ * is 'relevanssi_post_content', for excerpts it's
1855
+ * 'relevanssi_pre_excerpt_content'.
1856
+ */
1857
+ $search_array = apply_filters(
1858
+ 'relevanssi_page_builder_shortcodes',
1859
+ array(
1860
+ // Remove content.
1861
+ '/\[et_pb_code.*?\].*\[\/et_pb_code\]/im',
1862
+ '/\[et_pb_sidebar.*?\].*\[\/et_pb_sidebar\]/im',
1863
+ '/\[et_pb_fullwidth_slider.*?\].*\[\/et_pb_fullwidth_slider\]/im',
1864
+ '/\[vc_raw_html.*?\].*\[\/vc_raw_html\]/im',
1865
+ // Remove only the tags.
1866
+ '/\[\/?et_pb.*?\]/im',
1867
+ '/\[\/?vc.*?\]/im',
1868
+ '/\[\/?mk.*?\]/im',
1869
+ '/\[\/?cs_.*?\]/im',
1870
+ '/\[\/?av_.*?\]/im',
1871
+ '/\[\/?fusion_.*?\]/im',
1872
+ '/\[maxmegamenu.*?\]/im',
1873
+ '/\[ai1ec.*?\]/im',
1874
+ '/\[eme_.*?\]/im',
1875
+ '/\[layerslider.*?\]/im',
1876
+ ),
1877
+ $context
1878
+ );
1879
+ $content = preg_replace( $search_array, ' ', $content );
1880
+ return $content;
1881
+ }
lib/compatibility/gutenberg.php CHANGED
@@ -11,9 +11,7 @@
11
  */
12
 
13
  if ( RELEVANSSI_PREMIUM ) {
14
- // Gutenberg causes duplicate postmeta to appear in posts. This will remove the
15
- // extras when a post is saved.
16
- add_action( 'save_post', 'relevanssi_remove_duplicate_postmeta', 100 );
17
  }
18
 
19
  add_filter( 'relevanssi_post_content', 'relevanssi_gutenberg_block_rendering', 10 );
11
  */
12
 
13
  if ( RELEVANSSI_PREMIUM ) {
14
+ add_action( 'rest_after_insert_post', 'relevanssi_save_gutenberg_postdata' );
 
 
15
  }
16
 
17
  add_filter( 'relevanssi_post_content', 'relevanssi_gutenberg_block_rendering', 10 );
lib/contextual-help.php CHANGED
@@ -19,27 +19,36 @@ function relevanssi_admin_help() {
19
  global $wpdb;
20
 
21
  $screen = get_current_screen();
 
 
 
 
 
 
 
 
22
  $screen->add_help_tab(
23
  array(
24
  'id' => 'relevanssi-searching',
25
  'title' => __( 'Searching', 'relevanssi' ),
26
  'content' => '<ul>' .
27
- // Translators: %1$s is 'orderby', %2$s is the Codex page URL.
28
- '<li>' . sprintf( __( "To adjust the post order, you can use the %1\$s query parameter. With %1\$s, you can use multiple layers of different sorting methods. See <a href='%2\$s'>WordPress Codex</a> for more details on using arrays for orderby.", 'relevanssi' ), '<code>orderby</code>', 'https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters' ) . '</li>' .
29
  '<li>' . __( "Inside-word matching is disabled by default, because it increases garbage results that don't really match the search term. If you want to enable it, add the following function to your theme functions.php:", 'relevanssi' ) .
30
  '<pre>add_filter( \'relevanssi_fuzzy_query\', \'rlv_partial_inside_words\' );
31
  function rlv_partial_inside_words( $query ) {
32
  return "(relevanssi.term LIKE \'%#term#%\')";
33
  }</pre></li>' .
34
- // Translators: %s is 'Uncheck this if you use non-ASCII characters' option name.
35
- '<li>' . sprintf( __( 'To get inside-word highlights, uncheck the "%s" option. That has a side-effect of enabling the inside-word highlights.', 'relevanssi' ), __( 'Uncheck this if you use non-ASCII characters', 'relevanssi' ) ) . '</li>' .
36
- // Translators: %s is 'relevanssi_throttle_limit'.
37
- '<li>' . sprintf( __( 'In order to adjust the throttle limit, you can use the %s filter hook.', 'relevanssi' ), '<code>pre_option_relevanssi_throttle_limit</code>' ) .
38
  '<pre>add_filter( \'pre_option_relevanssi_throttle_limit\', function( $limit ) { return 200; } );</pre></li>' .
39
  '<li>' . __( "It's not usually necessary to adjust the limit from 500, but in some cases performance gains can be achieved by setting a lower limit. We don't suggest going under 200, as low values will make the results worse.", 'relevanssi' ) . '</li>' .
40
  '</ul>',
41
  )
42
  );
 
 
 
 
43
  $screen->add_help_tab(
44
  array(
45
  'id' => 'relevanssi-search-restrictions',
@@ -50,21 +59,25 @@ function rlv_partial_inside_words( $query ) {
50
  '<pre>&lt;input type="hidden" name="cats" value="10,14,17" /&gt;</pre></li>' .
51
  '<li>' . __( 'To restrict the search to posts tagged with alfa AND beta, you could add this to the search form:', 'relevanssi' ) .
52
  '<pre>&lt;input type="hidden" name="tag" value="alfa+beta" /&gt;</pre></li>' .
53
- // Translators: %s is the link to the Codex page.
54
- '<li>' . sprintf( __( 'For all the possible options, see the Codex documentation for %s.', 'relevanssi' ), '<a href="https://codex.wordpress.org/Class_Reference/WP_Query">WP_Query</a>' ) . '</li>' .
55
  '</ul>',
56
  )
57
  );
 
 
 
 
 
 
 
58
  $screen->add_help_tab(
59
  array(
60
  'id' => 'relevanssi-search-exclusions',
61
  'title' => __( 'Exclusions', 'relevanssi' ),
62
  'content' => '<ul>' .
63
- // Translators: %s is the link to the Codex page.
64
- '<li>' . sprintf( __( 'For more exclusion options, see the Codex documentation for %s. For example, to exclude tag ID 10, use', 'relevanssi' ), '<a href="https://codex.wordpress.org/Class_Reference/WP_Query">WP_Query</a>' ) .
65
  '<pre>&lt;input type="hidden" name="tag__not_in" value="10" /&gt;</pre></li>' .
66
- // Translators: %s is 'relevanssi_do_not_index'.
67
- '<li>' . sprintf( __( 'To exclude posts from the index and not just from the search, you can use the %s filter hook. This would not index posts that have a certain taxonomy term:', 'relevanssi' ), '<code>relevanssi_do_not_index</code>' ) .
68
  '<pre>add_filter( \'relevanssi_do_not_index\', \'rlv_index_filter\', 10, 2 );
69
  function rlv_index_filter( $block, $post_id ) {
70
  if ( has_term( \'jazz\', \'genre\', $post_id ) ) {
@@ -73,108 +86,137 @@ function rlv_partial_inside_words( $query ) {
73
  return $block;
74
  }
75
  </pre></li>' .
76
- // Translators: %s is a link to the Relevanssi knowledge base.
77
- '<li>' . sprintf( __( "For more examples, see <a href='%s'>the related knowledge base posts</a>.", 'relevanssi' ), 'https://www.relevanssi.com/tag/relevanssi_do_not_index/' ) . '</li>' .
78
  '</ul>',
79
  )
80
  );
 
 
 
 
 
 
81
  $screen->add_help_tab(
82
  array(
83
  'id' => 'relevanssi-logging',
84
  'title' => __( 'Logs', 'relevanssi' ),
85
  'content' => '<ul>' .
86
- // Translators: %s is 'relevanssi_user_searches_limit'.
87
- '<li>' . sprintf( __( 'By default, the User searches page shows 20 most common keywords. In order to see more, you can adjust the value with the %s filter hook, like this:', 'relevanssi' ), '<code>relevanssi_user_searches_limit</code>' ) .
88
  "<pre>add_filter( 'relevanssi_user_searches_limit', function() { return 50; } );</pre></li>" .
89
- // Translators: %s is the name of the database table.
90
- '<li>' . sprintf( __( 'The complete logs are stored in the %s database table, where you can access them if you need more information than what the User searches page provides.', 'relevanssi' ), '<code>' . $wpdb->prefix . 'relevanssi_log</code>' ) . '</li>' .
91
  '</ul>',
92
  )
93
  );
 
 
 
 
 
 
 
 
 
 
94
  $screen->add_help_tab(
95
  array(
96
  'id' => 'relevanssi-excerpts',
97
  'title' => __( 'Excerpts', 'relevanssi' ),
98
  'content' => '<ul>' .
99
  '<li>' . __( 'Building custom excerpts can be slow. If you are not actually using the excerpts, make sure you disable the option.', 'relevanssi' ) . '</li>' .
100
- // Translators: %s is 'the_excerpt()'.
101
- '<li>' . sprintf( __( 'Custom snippets require that the search results template uses %s to print out the excerpts.', 'relevanssi' ), '<code>the_excerpt()</code>' ) . '</li>' .
102
  '<li>' . __( 'Generally, Relevanssi generates the excerpts from post content. If you want to include custom field content in the excerpt-building, this can be done with a simple setting from the excerpt settings.', 'relevanssi' ) . '</li>' .
103
- // Translators: %1$s is 'relevanssi_pre_excerpt_content', %2$s is 'relevanssi_excerpt_content'.
104
- '<li>' . sprintf( __( 'If you want more control over what content Relevanssi uses to create the excerpts, you can use the %1$s and %2$s filter hooks to adjust the content.', 'relevanssi' ), '<code>relevanssi_pre_excerpt_content</code>', '<code>relevanssi_excerpt_content</code>' ) . '</li>' .
105
- // Translators: %s is 'relevanssi_disable_shortcodes_excerpt'.
106
- '<li>' . sprintf( __( 'Some shortcode do not work well with Relevanssi excerpt-generation. Relevanssi disables some shortcodes automatically to prevent problems. This can be adjusted with the %s filter hook.', 'relevanssi' ), '<code>relevanssi_disable_shortcodes_excerpt</code>' ) . '</li>' .
107
- // Translators: %s is 'relevanssi_optimize_excerpts'.
108
- '<li>' . sprintf( __( "If you want Relevanssi to build excerpts faster and don't mind that they may be less than perfect in quality, add a filter that returns true on hook %s.", 'relevanssi' ), '<code>relevanssi_optimize_excerpts</code>' ) .
109
  "<pre>add_filter( 'relevanssi_optimize_excerpts', '__return_true' );</pre></li>" .
110
  '</ul>',
111
  )
112
  );
 
 
 
 
113
  $screen->add_help_tab(
114
  array(
115
  'id' => 'relevanssi-highlights',
116
  'title' => __( 'Highlights', 'relevanssi' ),
117
  'content' => '<ul>' .
118
  '<li>' . __( "Title highlights don't appear automatically, because that led to problems with highlights appearing in wrong places and messing up navigation menus, for example.", 'relevanssi' ) . '</li>' .
119
- // Translators: %1$s is 'the_title()', %2$s is 'relevanssi_the_title()'.
120
- '<li>' . sprintf( __( 'In order to see title highlights from Relevanssi, replace %1$s in the search results template with %2$s. It does the same thing, but supports Relevanssi title highlights.', 'relevanssi' ), '<code>the_title()</code>', '<code>relevanssi_the_title()</code>' ) . '</li>' .
121
  '</ul>',
122
  )
123
  );
 
 
 
 
 
 
124
  $screen->add_help_tab(
125
  array(
126
  'id' => 'relevanssi-punctuation',
127
  'title' => __( 'Punctuation', 'relevanssi' ),
128
  'content' => '<ul>' .
129
  '<li>' . __( 'Relevanssi removes punctuation. Some punctuation is removed, some replaced with spaces. Advanced indexing settings include some of the more common settings people want to change.', 'relevanssi' ) . '</li>' .
130
- // Translators: %1$s is 'relevanssi_punctuation_filter', %2$s is 'relevanssi_remove_punctuation'.
131
- '<li>' . sprintf( __( 'For more fine-tuned changes, you can use %1$s filter hook to adjust what is replaced with what, and %2$s filter hook to completely override the default punctuation control.', 'relevanssi' ), '<code>relevanssi_punctuation_filter</code>', '<code>relevanssi_remove_punctuation</code>' ) . '</li>' .
132
- // Translators: %s is the URL to the Knowledge Base entry.
133
- '<li>' . sprintf( __( "For more examples, see <a href='%s'>the related knowledge base posts</a>.", 'relevanssi' ), 'https://www.relevanssi.com/tag/relevanssi_remove_punct/' ) . '</li>' .
134
  '</ul>',
135
  )
136
  );
 
 
 
 
 
 
 
 
 
 
137
  $screen->add_help_tab(
138
  array(
139
  'id' => 'relevanssi-helpful-shortcodes',
140
  'title' => __( 'Helpful shortcodes', 'relevanssi' ),
141
- 'content' => '<ul>' .
142
- // Translators: %s is '[noindex]'.
143
- '<li>' . sprintf( __( "If you have content that you don't want indexed, you can wrap that content in a %s shortcode.", 'relevanssi' ), '<code>[noindex]</code>' ) . '</li>' .
144
- // Translators: %s is '[searchform]'.
145
- '<li>' . sprintf( __( 'If you need a search form on some page on your site, you can use the %s shortcode to print out a basic search form.', 'relevanssi' ), '<code>[searchform]</code>' ) . '</li>' .
146
- // Translators: %1$s is '[searchform post_types="page"]', %2$s is '[searchform cats="10,14,17"]'.
147
- '<li>' . sprintf( __( 'If you need to add query variables to the search form, the shortcode takes parameters, which are then printed out as hidden input fields. To get a search form with a post type restriction, you can use %1$s. To restrict the search to categories 10, 14 and 17, you can use %2$s and so on.', 'relevanssi' ), '<code>[searchform post_types="page"]</code>', '<code>[searchform cats="10,14,17"]</code>' ) . '</li>' .
148
- // Translators: %1$s is 'dropdown', %2$s is '[searchform dropdown="category"]'.
149
- '<li>' . sprintf( __( 'You can use the %1$s parameter to add a taxonomy dropdown to the search form. Just use the name of the taxonomy, like %2$s. This works best with hierarchical taxonomies like categories with relatively few options available.', 'relevanssi' ), '<code>dropdown</code>', '<code>[searchform dropdown="category"]</code>' ) . '</li>' .
150
- '</ul>',
151
  )
152
  );
 
 
 
 
153
  $screen->add_help_tab(
154
  array(
155
  'id' => 'relevanssi-title-woocommerce',
156
  'title' => __( 'WooCommerce', 'relevanssi' ),
157
  'content' => '<ul>' .
158
  '<li>' . __( "If your SKUs include hyphens or other punctuation, do note that Relevanssi replaces most punctuation with spaces. That's going to cause issues with SKU searches.", 'relevanssi' ) . '</li>' .
159
- // Translators: %s is the Knowledge Base URL.
160
- '<li>' . sprintf( __( "For more details how to fix that issue, see <a href='%s'>WooCommerce tips in Relevanssi user manual</a>.", 'relevanssi' ), 'https://www.relevanssi.com/user-manual/woocommerce/' ) . '</li>' .
161
  '<li>' . __( "If you don't want to index products that are out of stock, excluded from the catalog or excluded from the search, there's a product visibility filtering method that is described in the user manual (see link above).", 'relevanssi' ) . '</li>' .
162
  '</ul>',
163
  )
164
  );
 
 
 
 
 
 
165
  $screen->add_help_tab(
166
  array(
167
  'id' => 'relevanssi-exact-match',
168
  'title' => __( 'Exact match bonus', 'relevanssi' ),
169
  'content' => '<ul>' .
170
- // Translators: %s is the name of the filter hook.
171
- '<li>' . sprintf( __( 'To adjust the amount of the exact match bonus, you can use the %s filter hook. It works like this:', 'relevanssi' ), '<code>relevanssi_exact_match_bonus</code>' ) .
172
  "<pre>add_filter( 'relevanssi_exact_match_bonus', 'rlv_adjust_bonus' );
173
  function rlv_adjust_bonus( \$bonus ) {
174
  return array( 'title' => 10, 'content' => 5 );
175
  }</li>" .
176
- // Translators: %1$s is the title weight and %2$s is the content weight.
177
- '<li>' . sprintf( esc_html__( 'The default values are %1$s for titles and %2$s for content.', 'relevanssi' ), '<code>5</code>', '<code>2</code>' ) . '</ul>',
178
  )
179
  );
180
  $screen->set_help_sidebar(
19
  global $wpdb;
20
 
21
  $screen = get_current_screen();
22
+
23
+ // Translators: %1$s is 'orderby', %2$s is the Codex page URL.
24
+ $orderby_parameters = sprintf( __( "To adjust the post order, you can use the %1\$s query parameter. With %1\$s, you can use multiple layers of different sorting methods. See <a href='%2\$s'>WordPress Codex</a> for more details on using arrays for orderby.", 'relevanssi' ), '<code>orderby</code>', 'https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters' );
25
+ // Translators: %s is 'Uncheck this if you use non-ASCII characters' option name.
26
+ $inside_word_highlights = sprintf( __( 'To get inside-word highlights, uncheck the "%s" option. That has a side-effect of enabling the inside-word highlights.', 'relevanssi' ), __( 'Uncheck this if you use non-ASCII characters', 'relevanssi' ) );
27
+ // Translators: %s is 'relevanssi_throttle_limit'.
28
+ $throttle_limit = sprintf( __( 'In order to adjust the throttle limit, you can use the %s filter hook.', 'relevanssi' ), '<code>pre_option_relevanssi_throttle_limit</code>' );
29
+
30
  $screen->add_help_tab(
31
  array(
32
  'id' => 'relevanssi-searching',
33
  'title' => __( 'Searching', 'relevanssi' ),
34
  'content' => '<ul>' .
35
+ "<li>$orderby_parameters</li>" .
 
36
  '<li>' . __( "Inside-word matching is disabled by default, because it increases garbage results that don't really match the search term. If you want to enable it, add the following function to your theme functions.php:", 'relevanssi' ) .
37
  '<pre>add_filter( \'relevanssi_fuzzy_query\', \'rlv_partial_inside_words\' );
38
  function rlv_partial_inside_words( $query ) {
39
  return "(relevanssi.term LIKE \'%#term#%\')";
40
  }</pre></li>' .
41
+ "<li>$inside_word_highlights</li>" .
42
+ "<li>$throttle_limit" .
 
 
43
  '<pre>add_filter( \'pre_option_relevanssi_throttle_limit\', function( $limit ) { return 200; } );</pre></li>' .
44
  '<li>' . __( "It's not usually necessary to adjust the limit from 500, but in some cases performance gains can be achieved by setting a lower limit. We don't suggest going under 200, as low values will make the results worse.", 'relevanssi' ) . '</li>' .
45
  '</ul>',
46
  )
47
  );
48
+
49
+ // Translators: %s is the link to the Codex page.
50
+ $codex_documentation = sprintf( __( 'For all the possible options, see the Codex documentation for %s.', 'relevanssi' ), '<a href="https://codex.wordpress.org/Class_Reference/WP_Query">WP_Query</a>' );
51
+
52
  $screen->add_help_tab(
53
  array(
54
  'id' => 'relevanssi-search-restrictions',
59
  '<pre>&lt;input type="hidden" name="cats" value="10,14,17" /&gt;</pre></li>' .
60
  '<li>' . __( 'To restrict the search to posts tagged with alfa AND beta, you could add this to the search form:', 'relevanssi' ) .
61
  '<pre>&lt;input type="hidden" name="tag" value="alfa+beta" /&gt;</pre></li>' .
62
+ "<li>$codex_documentation</li>" .
 
63
  '</ul>',
64
  )
65
  );
66
+ // Translators: %s is the link to the Codex page.
67
+ $exclusion_options = sprintf( __( 'For more exclusion options, see the Codex documentation for %s. For example, to exclude tag ID 10, use', 'relevanssi' ), '<a href="https://codex.wordpress.org/Class_Reference/WP_Query">WP_Query</a>' );
68
+ // Translators: %s is 'relevanssi_do_not_index'.
69
+ $exclusion_instructions = sprintf( __( 'To exclude posts from the index and not just from the search, you can use the %s filter hook. This would not index posts that have a certain taxonomy term:', 'relevanssi' ), '<code>relevanssi_do_not_index</code>' );
70
+ // Translators: %s is a link to the Relevanssi knowledge base.
71
+ $more_examples = sprintf( __( "For more examples, see <a href='%s'>the related knowledge base posts</a>.", 'relevanssi' ), 'https://www.relevanssi.com/tag/relevanssi_do_not_index/' );
72
+
73
  $screen->add_help_tab(
74
  array(
75
  'id' => 'relevanssi-search-exclusions',
76
  'title' => __( 'Exclusions', 'relevanssi' ),
77
  'content' => '<ul>' .
78
+ "<li>$exclusion_options" .
 
79
  '<pre>&lt;input type="hidden" name="tag__not_in" value="10" /&gt;</pre></li>' .
80
+ "<li>$exclusion_instructions" .
 
81
  '<pre>add_filter( \'relevanssi_do_not_index\', \'rlv_index_filter\', 10, 2 );
82
  function rlv_index_filter( $block, $post_id ) {
83
  if ( has_term( \'jazz\', \'genre\', $post_id ) ) {
86
  return $block;
87
  }
88
  </pre></li>' .
89
+ "<li>$more_examples</li>" .
 
90
  '</ul>',
91
  )
92
  );
93
+
94
+ // Translators: %s is 'relevanssi_user_searches_limit'.
95
+ $user_searches_limit = sprintf( __( 'By default, the User searches page shows 20 most common keywords. In order to see more, you can adjust the value with the %s filter hook, like this:', 'relevanssi' ), '<code>relevanssi_user_searches_limit</code>' );
96
+ // Translators: %s is the name of the database table.
97
+ $log_database = sprintf( __( 'The complete logs are stored in the %s database table, where you can access them if you need more information than what the User searches page provides.', 'relevanssi' ), '<code>' . $wpdb->prefix . 'relevanssi_log</code>' );
98
+
99
  $screen->add_help_tab(
100
  array(
101
  'id' => 'relevanssi-logging',
102
  'title' => __( 'Logs', 'relevanssi' ),
103
  'content' => '<ul>' .
104
+ "<li>$user_searches_limit" .
 
105
  "<pre>add_filter( 'relevanssi_user_searches_limit', function() { return 50; } );</pre></li>" .
106
+ "<li>$log_database</li>" .
 
107
  '</ul>',
108
  )
109
  );
110
+
111
+ // Translators: %s is 'the_excerpt()'.
112
+ $custom_snippets = sprintf( __( 'Custom snippets require that the search results template uses %s to print out the excerpts.', 'relevanssi' ), '<code>the_excerpt()</code>' );
113
+ // Translators: %1$s is 'relevanssi_pre_excerpt_content', %2$s is 'relevanssi_excerpt_content'.
114
+ $pre_excerpt_content = sprintf( __( 'If you want more control over what content Relevanssi uses to create the excerpts, you can use the %1$s and %2$s filter hooks to adjust the content.', 'relevanssi' ), '<code>relevanssi_pre_excerpt_content</code>', '<code>relevanssi_excerpt_content</code>' );
115
+ // Translators: %s is 'relevanssi_disable_shortcodes_excerpt'.
116
+ $disable_shortcodes = sprintf( __( 'Some shortcode do not work well with Relevanssi excerpt-generation. Relevanssi disables some shortcodes automatically to prevent problems. This can be adjusted with the %s filter hook.', 'relevanssi' ), '<code>relevanssi_disable_shortcodes_excerpt</code>' );
117
+ // Translators: %s is 'relevanssi_optimize_excerpts'.
118
+ $optimize_excerpts = sprintf( __( "If you want Relevanssi to build excerpts faster and don't mind that they may be less than perfect in quality, add a filter that returns true on hook %s.", 'relevanssi' ), '<code>relevanssi_optimize_excerpts</code>' );
119
+
120
  $screen->add_help_tab(
121
  array(
122
  'id' => 'relevanssi-excerpts',
123
  'title' => __( 'Excerpts', 'relevanssi' ),
124
  'content' => '<ul>' .
125
  '<li>' . __( 'Building custom excerpts can be slow. If you are not actually using the excerpts, make sure you disable the option.', 'relevanssi' ) . '</li>' .
126
+ "<li>$custom_snippets</li>" .
 
127
  '<li>' . __( 'Generally, Relevanssi generates the excerpts from post content. If you want to include custom field content in the excerpt-building, this can be done with a simple setting from the excerpt settings.', 'relevanssi' ) . '</li>' .
128
+ "<li>$pre_excerpt_content</li>" .
129
+ "<li>$disable_shortcodes</li>" .
130
+ "<li>$optimize_excerpts" .
 
 
 
131
  "<pre>add_filter( 'relevanssi_optimize_excerpts', '__return_true' );</pre></li>" .
132
  '</ul>',
133
  )
134
  );
135
+
136
+ // Translators: %1$s is 'the_title()', %2$s is 'relevanssi_the_title()'.
137
+ $the_title = sprintf( __( 'In order to see title highlights from Relevanssi, replace %1$s in the search results template with %2$s. It does the same thing, but supports Relevanssi title highlights.', 'relevanssi' ), '<code>the_title()</code>', '<code>relevanssi_the_title()</code>' );
138
+
139
  $screen->add_help_tab(
140
  array(
141
  'id' => 'relevanssi-highlights',
142
  'title' => __( 'Highlights', 'relevanssi' ),
143
  'content' => '<ul>' .
144
  '<li>' . __( "Title highlights don't appear automatically, because that led to problems with highlights appearing in wrong places and messing up navigation menus, for example.", 'relevanssi' ) . '</li>' .
145
+ "<li>$the_title</li>" .
 
146
  '</ul>',
147
  )
148
  );
149
+
150
+ // Translators: %1$s is 'relevanssi_punctuation_filter', %2$s is 'relevanssi_remove_punctuation'.
151
+ $remove_punctuation = sprintf( __( 'For more fine-tuned changes, you can use %1$s filter hook to adjust what is replaced with what, and %2$s filter hook to completely override the default punctuation control.', 'relevanssi' ), '<code>relevanssi_punctuation_filter</code>', '<code>relevanssi_remove_punctuation</code>' );
152
+ // Translators: %s is the URL to the Knowledge Base entry.
153
+ $remove_punct_guide = sprintf( __( "For more examples, see <a href='%s'>the related knowledge base posts</a>.", 'relevanssi' ), 'https://www.relevanssi.com/tag/relevanssi_remove_punct/' );
154
+
155
  $screen->add_help_tab(
156
  array(
157
  'id' => 'relevanssi-punctuation',
158
  'title' => __( 'Punctuation', 'relevanssi' ),
159
  'content' => '<ul>' .
160
  '<li>' . __( 'Relevanssi removes punctuation. Some punctuation is removed, some replaced with spaces. Advanced indexing settings include some of the more common settings people want to change.', 'relevanssi' ) . '</li>' .
161
+ "<li>$remove_punctuation</li>" .
162
+ "<li>$remove_punct_guide</li>" .
 
 
163
  '</ul>',
164
  )
165
  );
166
+
167
+ // Translators: %s is '[noindex]'.
168
+ $noindex = sprintf( __( "If you have content that you don't want indexed, you can wrap that content in a %s shortcode.", 'relevanssi' ), '<code>[noindex]</code>' );
169
+ // Translators: %s is '[searchform]'.
170
+ $searchform = sprintf( __( 'If you need a search form on some page on your site, you can use the %s shortcode to print out a basic search form.', 'relevanssi' ), '<code>[searchform]</code>' );
171
+ // Translators: %1$s is '[searchform post_types="page"]', %2$s is '[searchform cats="10,14,17"]'.
172
+ $searchform_cats = sprintf( __( 'If you need to add query variables to the search form, the shortcode takes parameters, which are then printed out as hidden input fields. To get a search form with a post type restriction, you can use %1$s. To restrict the search to categories 10, 14 and 17, you can use %2$s and so on.', 'relevanssi' ), '<code>[searchform post_types="page"]</code>', '<code>[searchform cats="10,14,17"]</code>' );
173
+ // Translators: %1$s is 'dropdown', %2$s is '[searchform dropdown="category"]'.
174
+ $searchform_dropdown = sprintf( __( 'You can use the %1$s parameter to add a taxonomy dropdown to the search form. Just use the name of the taxonomy, like %2$s. This works best with hierarchical taxonomies like categories with relatively few options available.', 'relevanssi' ), '<code>dropdown</code>', '<code>[searchform dropdown="category"]</code>' );
175
+
176
  $screen->add_help_tab(
177
  array(
178
  'id' => 'relevanssi-helpful-shortcodes',
179
  'title' => __( 'Helpful shortcodes', 'relevanssi' ),
180
+ 'content' => "<ul>
181
+ <li>$noindex</li>
182
+ <li>$searchform</li>
183
+ <li>$searchform_cats</li>
184
+ <li>$searchform_dropdown</li>
185
+ </ul>",
 
 
 
 
186
  )
187
  );
188
+
189
+ // Translators: %s is the Knowledge Base URL.
190
+ $woocommerce = sprintf( __( "For more details how to fix that issue, see <a href='%s'>WooCommerce tips in Relevanssi user manual</a>.", 'relevanssi' ), 'https://www.relevanssi.com/user-manual/woocommerce/' );
191
+
192
  $screen->add_help_tab(
193
  array(
194
  'id' => 'relevanssi-title-woocommerce',
195
  'title' => __( 'WooCommerce', 'relevanssi' ),
196
  'content' => '<ul>' .
197
  '<li>' . __( "If your SKUs include hyphens or other punctuation, do note that Relevanssi replaces most punctuation with spaces. That's going to cause issues with SKU searches.", 'relevanssi' ) . '</li>' .
198
+ "<li>$woocommerce</li>" .
 
199
  '<li>' . __( "If you don't want to index products that are out of stock, excluded from the catalog or excluded from the search, there's a product visibility filtering method that is described in the user manual (see link above).", 'relevanssi' ) . '</li>' .
200
  '</ul>',
201
  )
202
  );
203
+
204
+ // Translators: %s is the name of the filter hook.
205
+ $exact_match_bonus = sprintf( __( 'To adjust the amount of the exact match bonus, you can use the %s filter hook. It works like this:', 'relevanssi' ), '<code>relevanssi_exact_match_bonus</code>' );
206
+ // Translators: %1$s is the title weight and %2$s is the content weight.
207
+ $weights = sprintf( esc_html__( 'The default values are %1$s for titles and %2$s for content.', 'relevanssi' ), '<code>5</code>', '<code>2</code>' );
208
+
209
  $screen->add_help_tab(
210
  array(
211
  'id' => 'relevanssi-exact-match',
212
  'title' => __( 'Exact match bonus', 'relevanssi' ),
213
  'content' => '<ul>' .
214
+ "<li>$exact_match_bonus" .
 
215
  "<pre>add_filter( 'relevanssi_exact_match_bonus', 'rlv_adjust_bonus' );
216
  function rlv_adjust_bonus( \$bonus ) {
217
  return array( 'title' => 10, 'content' => 5 );
218
  }</li>" .
219
+ "<li>$weights</ul>",
 
220
  )
221
  );
222
  $screen->set_help_sidebar(
lib/excerpts-highlights.php CHANGED
@@ -61,6 +61,13 @@ function relevanssi_do_excerpt( $t_post, $query ) {
61
  // Minimum word length is -1, we don't care about it right now.
62
  $terms = relevanssi_tokenize( $query, $remove_stopwords, -1 );
63
 
 
 
 
 
 
 
 
64
  // These shortcodes cause problems with Relevanssi excerpts.
65
  $problem_shortcodes = array( 'layerslider', 'responsive-flipbook', 'breadcrumb', 'robogallery', 'gravityview', 'wp_show_posts' );
66
  /**
@@ -408,6 +415,29 @@ function relevanssi_highlight_terms( $content, $query, $in_docs = false ) {
408
 
409
  $remove_stopwords = true;
410
  $terms = array_keys( relevanssi_tokenize( $query, $remove_stopwords, $min_word_length ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  array_walk( $terms, 'relevanssi_array_walk_trim' ); // Numeric search terms begin with a space.
412
 
413
  if ( is_array( $query ) ) {
@@ -752,9 +782,9 @@ function relevanssi_count_matches( $words, $complete_text ) {
752
  $lowercase_text = relevanssi_strtolower( $complete_text, 'UTF-8' );
753
  $text = '';
754
 
755
- $word_boundaries_available = true;
756
  if ( 'on' === get_option( 'relevanssi_word_boundaries', 'off' ) ) {
757
- $word_boundaries_available = false;
758
  }
759
 
760
  $count_words = count( $words );
@@ -929,10 +959,8 @@ function relevanssi_extract_relevant_words( $terms, $content, $excerpt_length =
929
  $offset = 0;
930
  }
931
  }
932
-
933
  $excerpt_slice = array_slice( $words, $offset, $excerpt_length );
934
  $excerpt_slice = ' ' . implode( ' ', $excerpt_slice );
935
-
936
  $count_matches = relevanssi_count_matches( $terms, $excerpt_slice );
937
  if ( $count_matches > 0 && $count_matches > $best_excerpt_term_hits ) {
938
  $best_excerpt_term_hits = $count_matches;
@@ -995,8 +1023,8 @@ function relevanssi_add_accent_variations( $word ) {
995
  $replacement_arrays = apply_filters(
996
  'relevanssi_accents_replacement_arrays',
997
  array(
998
- 'from' => array( 'a', 'c', 'e', 'i', 'o', 'u', 'n', 'ss' ),
999
- 'to' => array( '(a|á|à|â)', '(c|ç)', '(e|é|è|ê|ë)', '(i|í|ì|î|ï)', '(o|ó|ò|ô|õ)', '(u|ú|ù|ü|û)', '(n|ñ)', '(ss|ß)' ),
1000
  )
1001
  );
1002
 
@@ -1007,12 +1035,8 @@ function relevanssi_add_accent_variations( $word ) {
1007
  $word_array[] = $char;
1008
  }
1009
  $word = implode( '-?', $word_array );
1010
-
1011
  $word = str_ireplace( $replacement_arrays['from'], $replacement_arrays['to'], $word );
1012
-
1013
  $word = preg_replace( '/s$/', "(s|'s|’s)", $word );
1014
- $word = preg_replace( '/^o/', "(o|o'|o’)", $word );
1015
-
1016
  $word = str_replace( '\-?/', '\/', $word );
1017
 
1018
  return $word;
@@ -1084,51 +1108,6 @@ function relevanssi_get_custom_field_content( $post_id ) {
1084
  return apply_filters( 'relevanssi_excerpt_custom_field_content', $custom_field_content );
1085
  }
1086
 
1087
- /**
1088
- * Removes page builder short codes from content.
1089
- *
1090
- * Page builder shortcodes cause problems in excerpts. This function cleans them
1091
- * out.
1092
- *
1093
- * @param string $content The content to clean.
1094
- *
1095
- * @return string The content without page builder shortcodes.
1096
- */
1097
- function relevanssi_remove_page_builder_shortcodes( $content ) {
1098
- /**
1099
- * Filters the page builder shortcode.
1100
- *
1101
- * @param array An array of page builder shortcode regexes.
1102
- */
1103
- $search_array = apply_filters(
1104
- 'relevanssi_page_builder_shortcodes',
1105
- array(
1106
- // Remove content.
1107
- '/\[et_pb_code.*?\].*\[\/et_pb_code\]/im',
1108
- '/\[et_pb_sidebar.*?\].*\[\/et_pb_sidebar\]/im',
1109
- '/\[et_pb_fullwidth_slider.*?\].*\[\/et_pb_fullwidth_slider\]/im',
1110
- '/\[vc_raw_html.*?\].*\[\/vc_raw_html\]/im',
1111
- // Remove only the tags.
1112
- '/\[\/?et_pb.*?\]/im',
1113
- '/\[\/?vc.*?\]/im',
1114
- '/\[\/?mk.*?\]/im',
1115
- '/\[\/?cs_.*?\]/im',
1116
- '/\[\/?av_.*?\]/im',
1117
- '/\[\/?fusion_.*?\]/im',
1118
- // Max Mega Menu doesn't work in excerpts.
1119
- '/\[maxmegamenu.*?\]/im',
1120
- // All-in-one Events Calendar shortcode doesn't look good.
1121
- '/\[ai1ec.*?\]/im',
1122
- // Events Made Easy Calendar shortcodes should be removed.
1123
- '/\[eme_.*?\]/im',
1124
- // Layer Slider.
1125
- '/\[layerslider.*?\]/im',
1126
- )
1127
- );
1128
- $content = preg_replace( $search_array, '', $content );
1129
- return $content;
1130
- }
1131
-
1132
  /**
1133
  * Kills the autoembed filter hook on 'the_content'.
1134
  *
61
  // Minimum word length is -1, we don't care about it right now.
62
  $terms = relevanssi_tokenize( $query, $remove_stopwords, -1 );
63
 
64
+ if ( is_array( $query ) ) {
65
+ $untokenized_terms = array_filter( $query );
66
+ } else {
67
+ $untokenized_terms = array_filter( explode( ' ', $query ) );
68
+ }
69
+ $terms = array_merge( array_flip( $untokenized_terms ), $terms );
70
+
71
  // These shortcodes cause problems with Relevanssi excerpts.
72
  $problem_shortcodes = array( 'layerslider', 'responsive-flipbook', 'breadcrumb', 'robogallery', 'gravityview', 'wp_show_posts' );
73
  /**
415
 
416
  $remove_stopwords = true;
417
  $terms = array_keys( relevanssi_tokenize( $query, $remove_stopwords, $min_word_length ) );
418
+
419
+ if ( is_array( $query ) ) {
420
+ $untokenized_terms = array_filter(
421
+ $query,
422
+ function( $value ) use ( $min_word_length ) {
423
+ if ( relevanssi_strlen( $value ) > $min_word_length ) {
424
+ return true;
425
+ }
426
+ return false;
427
+ }
428
+ );
429
+ } else {
430
+ $untokenized_terms = array_filter(
431
+ explode( ' ', $query ),
432
+ function( $value ) use ( $min_word_length ) {
433
+ if ( relevanssi_strlen( $value ) > $min_word_length ) {
434
+ return true;
435
+ }
436
+ return false;
437
+ }
438
+ );
439
+ }
440
+ $terms = array_unique( array_merge( $untokenized_terms, $terms ) );
441
  array_walk( $terms, 'relevanssi_array_walk_trim' ); // Numeric search terms begin with a space.
442
 
443
  if ( is_array( $query ) ) {
782
  $lowercase_text = relevanssi_strtolower( $complete_text, 'UTF-8' );
783
  $text = '';
784
 
785
+ $word_boundaries_available = false;
786
  if ( 'on' === get_option( 'relevanssi_word_boundaries', 'off' ) ) {
787
+ $word_boundaries_available = true;
788
  }
789
 
790
  $count_words = count( $words );
959
  $offset = 0;
960
  }
961
  }
 
962
  $excerpt_slice = array_slice( $words, $offset, $excerpt_length );
963
  $excerpt_slice = ' ' . implode( ' ', $excerpt_slice );
 
964
  $count_matches = relevanssi_count_matches( $terms, $excerpt_slice );
965
  if ( $count_matches > 0 && $count_matches > $best_excerpt_term_hits ) {
966
  $best_excerpt_term_hits = $count_matches;
1023
  $replacement_arrays = apply_filters(
1024
  'relevanssi_accents_replacement_arrays',
1025
  array(
1026
+ 'from' => array( 'a', 'c', 'e', 'i', 'o', 'u', 'n', "'" ),
1027
+ 'to' => array( '(a|á|à|â)', '(c|ç)', '(e|é|è|ê|ë)', '(i|í|ì|î|ï)', '(o|ó|ò|ô|õ)', '(u|ú|ù|ü|û)', '(n|ñ)', "('|’)?" ),
1028
  )
1029
  );
1030
 
1035
  $word_array[] = $char;
1036
  }
1037
  $word = implode( '-?', $word_array );
 
1038
  $word = str_ireplace( $replacement_arrays['from'], $replacement_arrays['to'], $word );
 
1039
  $word = preg_replace( '/s$/', "(s|'s|’s)", $word );
 
 
1040
  $word = str_replace( '\-?/', '\/', $word );
1041
 
1042
  return $word;
1108
  return apply_filters( 'relevanssi_excerpt_custom_field_content', $custom_field_content );
1109
  }
1110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1111
  /**
1112
  * Kills the autoembed filter hook on 'the_content'.
1113
  *
lib/indexing.php CHANGED
@@ -99,6 +99,14 @@ function relevanssi_generate_indexing_query( $valid_status, $extend = false, $re
99
  global $wpdb, $relevanssi_variables;
100
  $relevanssi_table = $relevanssi_variables['relevanssi_table'];
101
 
 
 
 
 
 
 
 
 
102
  /**
103
  * Filters the WHERE restriction for indexing queries.
104
  *
@@ -1176,6 +1184,8 @@ function relevanssi_index_custom_fields( &$insert_data, $post_id, $custom_fields
1176
  relevanssi_add_repeater_fields( $custom_fields, $post_id );
1177
  }
1178
 
 
 
1179
  if ( $debug ) {
1180
  relevanssi_debug_echo( 'Custom fields to index: ' . implode( ', ', $custom_fields ) );
1181
  }
@@ -1518,6 +1528,7 @@ function relevanssi_disable_shortcodes() {
1518
  'gravityform', // Gravity Forms.
1519
  'sdm_latest_downloads', // SDM Simple Download Monitor.
1520
  'slimstat', // Slimstat Analytics.
 
1521
  );
1522
 
1523
  $disable_shortcodes = get_option( 'relevanssi_disable_shortcodes' );
99
  global $wpdb, $relevanssi_variables;
100
  $relevanssi_table = $relevanssi_variables['relevanssi_table'];
101
 
102
+ if ( 'off' === get_option( 'relevanssi_index_image_files', 'off' ) ) {
103
+ $restriction .= "
104
+ AND post.ID NOT IN (
105
+ SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment'
106
+ AND post_mime_type LIKE 'image%' )
107
+ ";
108
+ }
109
+
110
  /**
111
  * Filters the WHERE restriction for indexing queries.
112
  *
1184
  relevanssi_add_repeater_fields( $custom_fields, $post_id );
1185
  }
1186
 
1187
+ $custom_fields = array_filter( $custom_fields );
1188
+
1189
  if ( $debug ) {
1190
  relevanssi_debug_echo( 'Custom fields to index: ' . implode( ', ', $custom_fields ) );
1191
  }
1528
  'gravityform', // Gravity Forms.
1529
  'sdm_latest_downloads', // SDM Simple Download Monitor.
1530
  'slimstat', // Slimstat Analytics.
1531
+ 'ninja_tables', // Ninja Tables.
1532
  );
1533
 
1534
  $disable_shortcodes = get_option( 'relevanssi_disable_shortcodes' );
lib/init.php CHANGED
@@ -45,8 +45,9 @@ 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 );
 
50
 
51
  // Permalink handling.
52
  add_filter( 'the_permalink', 'relevanssi_permalink', 10, 2 );
@@ -200,6 +201,11 @@ function relevanssi_init() {
200
  if ( defined( 'NINJA_TABLES_VERSION' ) ) {
201
  require_once 'compatibility/ninjatables.php';
202
  }
 
 
 
 
 
203
  }
204
 
205
  /**
@@ -424,7 +430,7 @@ function relevanssi_create_database_tables( $relevanssi_db_version ) {
424
  update_option( 'relevanssi_db_version', $relevanssi_db_version );
425
  }
426
 
427
- if ( $wpdb->get_var( "SELECT COUNT(*) FROM $relevanssi_stopword_table WHERE 1" ) < 1 ) { // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
428
  relevanssi_populate_stopwords();
429
  }
430
  }
45
  add_action( 'relevanssi_trim_logs', 'relevanssi_trim_logs' );
46
  add_action( 'relevanssi_custom_field_value', 'relevanssi_filter_custom_fields', 10, 2 );
47
 
48
+ // Page builder shortcodes.
49
  add_filter( 'relevanssi_pre_excerpt_content', 'relevanssi_remove_page_builder_shortcodes', 9 );
50
+ add_filter( 'relevanssi_post_content', 'relevanssi_remove_page_builder_shortcodes', 9 );
51
 
52
  // Permalink handling.
53
  add_filter( 'the_permalink', 'relevanssi_permalink', 10, 2 );
201
  if ( defined( 'NINJA_TABLES_VERSION' ) ) {
202
  require_once 'compatibility/ninjatables.php';
203
  }
204
+
205
+ // For problems in 2.5.0 / 4.4.0. Remove eventually.
206
+ if ( empty( get_option( 'relevanssi_stopwords', '' ) ) ) {
207
+ relevanssi_populate_stopwords();
208
+ }
209
  }
210
 
211
  /**
430
  update_option( 'relevanssi_db_version', $relevanssi_db_version );
431
  }
432
 
433
+ if ( empty( get_option( 'relevanssi_stopwords', '' ) ) ) {
434
  relevanssi_populate_stopwords();
435
  }
436
  }
lib/install.php CHANGED
@@ -100,6 +100,7 @@ function _relevanssi_install() {
100
  add_option( 'relevanssi_index_comments', 'none' );
101
  add_option( 'relevanssi_index_excerpt', 'off' );
102
  add_option( 'relevanssi_index_fields', '' );
 
103
  add_option( 'relevanssi_index_post_types', array( 'post', 'page' ) );
104
  add_option( 'relevanssi_index_taxonomies_list', array() );
105
  add_option( 'relevanssi_indexed', '' );
@@ -119,6 +120,7 @@ function _relevanssi_install() {
119
  add_option( 'relevanssi_respect_exclude', 'on' );
120
  add_option( 'relevanssi_show_matches', '' );
121
  add_option( 'relevanssi_show_matches_text', '(Search hits: %body% in body, %title% in title, %categories% in categories, %tags% in tags, %taxonomies% in other taxonomies, %comments% in comments. Score: %score%)' );
 
122
  add_option( 'relevanssi_synonyms', '' );
123
  add_option( 'relevanssi_throttle', 'on' );
124
  add_option( 'relevanssi_throttle_limit', '500' );
100
  add_option( 'relevanssi_index_comments', 'none' );
101
  add_option( 'relevanssi_index_excerpt', 'off' );
102
  add_option( 'relevanssi_index_fields', '' );
103
+ add_option( 'relevanssi_index_image_files', 'on' );
104
  add_option( 'relevanssi_index_post_types', array( 'post', 'page' ) );
105
  add_option( 'relevanssi_index_taxonomies_list', array() );
106
  add_option( 'relevanssi_indexed', '' );
120
  add_option( 'relevanssi_respect_exclude', 'on' );
121
  add_option( 'relevanssi_show_matches', '' );
122
  add_option( 'relevanssi_show_matches_text', '(Search hits: %body% in body, %title% in title, %categories% in categories, %tags% in tags, %taxonomies% in other taxonomies, %comments% in comments. Score: %score%)' );
123
+ add_option( 'relevanssi_stopwords', '' );
124
  add_option( 'relevanssi_synonyms', '' );
125
  add_option( 'relevanssi_throttle', 'on' );
126
  add_option( 'relevanssi_throttle_limit', '500' );
lib/interface.php CHANGED
@@ -131,6 +131,10 @@ function update_relevanssi_options() {
131
  if ( ! isset( $_REQUEST['relevanssi_expand_shortcodes'] ) ) {
132
  $_REQUEST['relevanssi_expand_shortcodes'] = 'off';
133
  }
 
 
 
 
134
  }
135
 
136
  if ( 'searching' === $_REQUEST['tab'] ) {
@@ -309,7 +313,7 @@ function update_relevanssi_options() {
309
  }
310
  if ( 'some' === $_REQUEST['relevanssi_index_fields_select'] ) {
311
  if ( isset( $_REQUEST['relevanssi_index_fields'] ) ) {
312
- $fields_option = $_REQUEST['relevanssi_index_fields'];
313
  }
314
  }
315
  update_option( 'relevanssi_index_fields', $fields_option );
@@ -413,6 +417,9 @@ function update_relevanssi_options() {
413
  if ( isset( $_REQUEST['relevanssi_index_excerpt'] ) ) {
414
  update_option( 'relevanssi_index_excerpt', $_REQUEST['relevanssi_index_excerpt'] );
415
  }
 
 
 
416
  if ( isset( $_REQUEST['relevanssi_fuzzy'] ) ) {
417
  update_option( 'relevanssi_fuzzy', $_REQUEST['relevanssi_fuzzy'] );
418
  }
@@ -630,16 +637,15 @@ function relevanssi_query_log() {
630
  print( "<form method='post'>" );
631
  wp_nonce_field( 'relevanssi_reset_logs', '_relresnonce', true, true );
632
  printf(
633
- '<p><label for="relevanssi_reset_code">%s</label></p></form>',
634
- sprintf(
635
- // Translators: %1$s is the input field, %2$s is the submit button.
636
- __( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
637
- 'To reset the logs, type "reset" into the box here %1$s and click %2$s',
638
- 'relevanssi'
639
- ),
640
- ' <input type="text" id="relevanssi_reset_code" name="relevanssi_reset_code" />',
641
- ' <input type="submit" name="relevanssi_reset" value="Reset" class="button" />'
642
- )
643
  );
644
  }
645
 
@@ -978,6 +984,7 @@ function relevanssi_add_admin_scripts( $hook ) {
978
  'reload_state' => __( 'Reload the page to refresh the state of the index.', 'relevanssi' ),
979
  'pdf_reset_confirm' => __( 'Are you sure you want to delete all attachment content from the index?', 'relevanssi' ),
980
  'pdf_reset_done' => __( 'Relevanssi attachment data wiped clean.', 'relevanssi' ),
 
981
  'hour' => __( 'hour', 'relevanssi' ),
982
  'hours' => __( 'hours', 'relevanssi' ),
983
  'about' => __( 'about', 'relevanssi' ),
131
  if ( ! isset( $_REQUEST['relevanssi_expand_shortcodes'] ) ) {
132
  $_REQUEST['relevanssi_expand_shortcodes'] = 'off';
133
  }
134
+
135
+ if ( ! isset( $_REQUEST['relevanssi_index_image_files'] ) ) {
136
+ $_REQUEST['relevanssi_index_image_files'] = 'off';
137
+ }
138
  }
139
 
140
  if ( 'searching' === $_REQUEST['tab'] ) {
313
  }
314
  if ( 'some' === $_REQUEST['relevanssi_index_fields_select'] ) {
315
  if ( isset( $_REQUEST['relevanssi_index_fields'] ) ) {
316
+ $fields_option = rtrim( $_REQUEST['relevanssi_index_fields'], " \t\n\r\0\x0B," );
317
  }
318
  }
319
  update_option( 'relevanssi_index_fields', $fields_option );
417
  if ( isset( $_REQUEST['relevanssi_index_excerpt'] ) ) {
418
  update_option( 'relevanssi_index_excerpt', $_REQUEST['relevanssi_index_excerpt'] );
419
  }
420
+ if ( isset( $_REQUEST['relevanssi_index_image_files'] ) ) {
421
+ update_option( 'relevanssi_index_image_files', $_REQUEST['relevanssi_index_image_files'] );
422
+ }
423
  if ( isset( $_REQUEST['relevanssi_fuzzy'] ) ) {
424
  update_option( 'relevanssi_fuzzy', $_REQUEST['relevanssi_fuzzy'] );
425
  }
637
  print( "<form method='post'>" );
638
  wp_nonce_field( 'relevanssi_reset_logs', '_relresnonce', true, true );
639
  printf(
640
+ '<p><label for="relevanssi_reset_code">%s</label>
641
+ <input type="text" id="relevanssi_reset_code" name="relevanssi_reset_code" />
642
+ <input type="submit" name="relevanssi_reset" value="%s" class="button" /></p></form>',
643
+ // Translators: do not translate "reset".
644
+ esc_html__(
645
+ 'To reset the logs, type "reset" into the box here and click the Reset button',
646
+ 'relevanssi'
647
+ ),
648
+ esc_html__( 'Reset', 'relevanssi' )
 
649
  );
650
  }
651
 
984
  'reload_state' => __( 'Reload the page to refresh the state of the index.', 'relevanssi' ),
985
  'pdf_reset_confirm' => __( 'Are you sure you want to delete all attachment content from the index?', 'relevanssi' ),
986
  'pdf_reset_done' => __( 'Relevanssi attachment data wiped clean.', 'relevanssi' ),
987
+ 'pdf_reset_problems' => __( 'There were problems wiping the Relevanssi attachment data clean.', 'relevanssi' ),
988
  'hour' => __( 'hour', 'relevanssi' ),
989
  'hours' => __( 'hours', 'relevanssi' ),
990
  'about' => __( 'about', 'relevanssi' ),
lib/search.php CHANGED
@@ -1000,7 +1000,9 @@ function relevanssi_do_query( &$query ) {
1000
  * @return string The query with the LIMIT parameter added, if necessary.
1001
  */
1002
  function relevanssi_limit_filter( $query ) {
1003
- if ( 'on' === get_option( 'relevanssi_throttle', 'on' ) ) {
 
 
1004
  $limit = get_option( 'relevanssi_throttle_limit', 500 );
1005
  if ( ! is_numeric( $limit ) ) {
1006
  $limit = 500;
1000
  * @return string The query with the LIMIT parameter added, if necessary.
1001
  */
1002
  function relevanssi_limit_filter( $query ) {
1003
+ $termless_search = strstr( $query, 'relevanssi.term = relevanssi.term' );
1004
+
1005
+ if ( $termless_search || 'on' === get_option( 'relevanssi_throttle', 'on' ) ) {
1006
  $limit = get_option( 'relevanssi_throttle_limit', 500 );
1007
  if ( ! is_numeric( $limit ) ) {
1008
  $limit = 500;
lib/stopwords.php CHANGED
@@ -9,28 +9,27 @@
9
  */
10
 
11
  /**
12
- * Reads automatically the correct stopwords for the current language set in WPLANG.
 
13
  *
14
  * @global object $wpdb The WordPress database interface.
15
  * @global array $relevanssi_variables The global Relevanssi variables array.
16
  */
17
  function relevanssi_populate_stopwords() {
18
- global $wpdb, $relevanssi_variables;
19
 
20
- $lang = get_option( 'WPLANG' );
21
- if ( empty( $lang ) && defined( 'WPLANG' ) && '' !== WPLANG ) {
22
- $lang = WPLANG;
23
- }
24
- if ( empty( $lang ) ) {
25
- $lang = 'en_US';
26
- }
27
 
28
- if ( file_exists( $relevanssi_variables['plugin_dir'] . 'stopwords/stopwords.' . $lang ) ) {
29
- include $relevanssi_variables['plugin_dir'] . 'stopwords/stopwords.' . $lang;
30
 
31
- if ( is_array( $stopwords ) && count( $stopwords ) > 0 ) {
32
- foreach ( $stopwords as $word ) {
33
- $wpdb->query( $wpdb->prepare( 'INSERT IGNORE INTO ' . $relevanssi_variables['stopword_table'] . ' (stopword) VALUES (%s)', trim( $word ) ) ); // WPCS: unprepared SQL ok.
34
  }
35
  }
36
  }
@@ -39,29 +38,15 @@ function relevanssi_populate_stopwords() {
39
  /**
40
  * Fetches the list of stopwords.
41
  *
42
- * Gets the list of stopwords from $relevanssi_variables, but if it's empty, fills
43
- * the array from the database table.
44
- *
45
- * @global object $wpdb The WordPress database interface.
46
- * @global array $relevanssi_variables The global Relevanssi variables array.
47
  *
48
  * @return array An array of stopwords.
49
  */
50
  function relevanssi_fetch_stopwords() {
51
- global $wpdb, $relevanssi_variables;
 
52
 
53
- if ( ! isset( $relevanssi_variables['stopword_list'] ) ) {
54
- $relevanssi_variables['stopword_list'] = array();
55
- }
56
-
57
- if ( count( $relevanssi_variables['stopword_list'] ) < 1 ) {
58
- $results = $wpdb->get_results( 'SELECT stopword FROM ' . $relevanssi_variables['stopword_table'] ); // WPCS: unprepared SQL ok.
59
- foreach ( $results as $word ) {
60
- $relevanssi_variables['stopword_list'][] = $word->stopword;
61
- }
62
- }
63
-
64
- return $relevanssi_variables['stopword_list'];
65
  }
66
 
67
  /**
@@ -126,37 +111,44 @@ function relevanssi_add_stopword( $term, $verbose = true ) {
126
  * @return boolean True if success, false if not.
127
  */
128
  function relevanssi_add_single_stopword( $term ) {
129
- global $wpdb, $relevanssi_variables;
130
  if ( empty( $term ) ) {
131
  return false;
132
  }
133
 
134
- $term = stripslashes( $term );
135
- $term = esc_sql( $wpdb->esc_like( $term ) );
136
 
137
- $success = $wpdb->query( $wpdb->prepare( 'INSERT IGNORE INTO ' . $relevanssi_variables['stopword_table'] . ' (stopword) VALUES (%s)', $term ) ); // WPCS: unprepared SQL ok, Relevanssi table name.
 
 
138
 
139
- if ( $success ) {
140
- // Remove from index.
141
- $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $relevanssi_variables['relevanssi_table'] . ' WHERE term=%s', $term ) ); // WPCS: unprepared SQL ok, Relevanssi table name.
142
- return true;
143
- } else {
144
  return false;
145
  }
 
 
 
 
 
 
 
 
 
 
 
 
146
  }
147
 
148
  /**
149
  * Removes all stopwords.
150
  *
151
- * Truncates the wp_relevanssi_stopwords database table.
152
- *
153
- * @global object $wpdb The WP database interface.
154
- * @global array $relevanssi_variables The global Relevanssi variables.
155
  */
156
  function relevanssi_remove_all_stopwords() {
157
- global $wpdb, $relevanssi_variables;
158
-
159
- $success = $wpdb->query( 'TRUNCATE ' . $relevanssi_variables['stopword_table'] ); // WPCS: unprepared SQL ok, Relevanssi table name.
160
 
161
  if ( $success ) {
162
  printf( "<div id='message' class='updated fade'><p>%s</p></div>", esc_html__( 'All stopwords removed! Remember to re-index.', 'relevanssi' ) );
@@ -177,9 +169,21 @@ function relevanssi_remove_all_stopwords() {
177
  * @return boolean True if success, false if not.
178
  */
179
  function relevanssi_remove_stopword( $term, $verbose = true ) {
180
- global $wpdb, $relevanssi_variables;
 
 
 
 
 
 
 
 
 
 
181
 
182
- $success = $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $relevanssi_variables['stopword_table'] . ' WHERE stopword=%s', $term ) ); // WPCS: unprepared SQL ok, Relevanssi table name.
 
 
183
 
184
  if ( $success ) {
185
  if ( $verbose ) {
9
  */
10
 
11
  /**
12
+ * Reads automatically the correct stopwords for the current language set in
13
+ * WPLANG.
14
  *
15
  * @global object $wpdb The WordPress database interface.
16
  * @global array $relevanssi_variables The global Relevanssi variables array.
17
  */
18
  function relevanssi_populate_stopwords() {
19
+ global $relevanssi_variables, $wpdb;
20
 
21
+ $stopword_table = $relevanssi_variables['stopword_table'];
22
+ $stopwords_from_table = $wpdb->get_col( "SELECT * FROM $stopword_table" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
23
+ if ( count( $stopwords_from_table ) > 1 ) {
24
+ array_walk( $stopwords_from_table, 'relevanssi_add_single_stopword' );
25
+ } else {
26
+ $lang = get_option( 'WPLANG', 'en_US' );
 
27
 
28
+ if ( file_exists( $relevanssi_variables['plugin_dir'] . 'stopwords/stopwords.' . $lang ) ) {
29
+ include $relevanssi_variables['plugin_dir'] . 'stopwords/stopwords.' . $lang;
30
 
31
+ if ( is_array( $stopwords ) ) {
32
+ array_walk( $stopwords, 'relevanssi_add_single_stopword' );
 
33
  }
34
  }
35
  }
38
  /**
39
  * Fetches the list of stopwords.
40
  *
41
+ * Gets the list of stopwords from the relevanssi_stopwords option.
 
 
 
 
42
  *
43
  * @return array An array of stopwords.
44
  */
45
  function relevanssi_fetch_stopwords() {
46
+ $stopwords = get_option( 'relevanssi_stopwords', '' );
47
+ $stopword_list = explode( ',', $stopwords );
48
 
49
+ return $stopword_list;
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
 
52
  /**
111
  * @return boolean True if success, false if not.
112
  */
113
  function relevanssi_add_single_stopword( $term ) {
 
114
  if ( empty( $term ) ) {
115
  return false;
116
  }
117
 
118
+ $term = stripslashes( relevanssi_strtolower( $term ) );
 
119
 
120
+ $stopwords = get_option( 'relevanssi_stopwords', '' );
121
+ if ( ! empty( $stopwords ) ) {
122
+ $stopwords .= ',';
123
 
124
+ }
125
+ $stopwords .= $term;
126
+ $success = update_option( 'relevanssi_stopwords', $stopwords );
127
+
128
+ if ( ! $success ) {
129
  return false;
130
  }
131
+
132
+ global $wpdb, $relevanssi_variables;
133
+
134
+ // Remove from index.
135
+ $wpdb->query(
136
+ $wpdb->prepare(
137
+ 'DELETE FROM ' . $relevanssi_variables['relevanssi_table'] . ' WHERE term=%s', // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
138
+ $term
139
+ )
140
+ );
141
+
142
+ return true;
143
  }
144
 
145
  /**
146
  * Removes all stopwords.
147
  *
148
+ * Empties the relevanssi_stopwords option.
 
 
 
149
  */
150
  function relevanssi_remove_all_stopwords() {
151
+ $success = update_option( 'relevanssi_stopwords', '' );
 
 
152
 
153
  if ( $success ) {
154
  printf( "<div id='message' class='updated fade'><p>%s</p></div>", esc_html__( 'All stopwords removed! Remember to re-index.', 'relevanssi' ) );
169
  * @return boolean True if success, false if not.
170
  */
171
  function relevanssi_remove_stopword( $term, $verbose = true ) {
172
+ $stopwords = get_option( 'relevanssi_stopwords', '' );
173
+ $success = false;
174
+
175
+ $stopwords_array = explode( ',', $stopwords );
176
+ if ( is_array( $stopwords_array ) ) {
177
+ $stopwords_array = array_filter(
178
+ $stopwords_array,
179
+ function( $v ) use ( $term ) {
180
+ return $v !== $term;
181
+ }
182
+ );
183
 
184
+ $stopwords = implode( ',', $stopwords_array );
185
+ $success = update_option( 'relevanssi_stopwords', $stopwords );
186
+ }
187
 
188
  if ( $success ) {
189
  if ( $verbose ) {
lib/tabs/excerpts-tab.php CHANGED
@@ -83,19 +83,16 @@ function relevanssi_excerpts_tab() {
83
 
84
  <h2 id="excerpts"><?php esc_html_e( 'Custom excerpts/snippets', 'relevanssi' ); ?></h2>
85
 
86
- <table class="form-table">
87
  <tr>
88
  <th scope="row">
89
  <?php esc_html_e( 'Custom search result snippets', 'relevanssi' ); ?>
90
  </th>
91
  <td>
92
- <fieldset>
93
- <legend class="screen-reader-text"><?php esc_html_e( 'Create custom search result snippets', 'relevanssi' ); ?></legend>
94
  <label >
95
  <input type='checkbox' name='relevanssi_excerpts' id='relevanssi_excerpts' <?php echo esc_html( $excerpts ); ?> />
96
  <?php esc_html_e( 'Create custom search result snippets', 'relevanssi' ); ?>
97
  </label>
98
- </fieldset>
99
  <p class="description"><?php esc_html_e( 'Only enable this if you actually use the custom excerpts.', 'relevanssi' ); ?></p>
100
  <?php
101
  $theme = wp_get_theme();
@@ -171,8 +168,6 @@ function relevanssi_excerpts_tab() {
171
  <?php esc_html_e( 'Use custom fields for excerpts', 'relevanssi' ); ?>
172
  </th>
173
  <td>
174
- <fieldset>
175
- <legend class="screen-reader-text"><?php esc_html_e( 'Use custom field content for building excerpts', 'relevanssi' ); ?></legend>
176
  <label>
177
  <input type='checkbox' name='relevanssi_excerpt_custom_fields' id='relevanssi_excerpt_custom_fields' <?php echo esc_html( $excerpt_custom_fields ); ?>
178
  <?php
@@ -183,7 +178,6 @@ function relevanssi_excerpts_tab() {
183
  />
184
  <?php esc_html_e( 'Use custom field content for building excerpts', 'relevanssi' ); ?>
185
  </label>
186
- </fieldset>
187
  <p class="description"><?php esc_html_e( 'Use the custom fields setting for indexing for excerpt-making as well. Enabling this option will show custom field content in Relevanssi-generated excerpts.', 'relevanssi' ); ?>
188
  <?php
189
  if ( RELEVANSSI_PREMIUM ) {
@@ -219,7 +213,7 @@ function relevanssi_excerpts_tab() {
219
  echo 'relevanssi_disabled';
220
  }
221
  ?>
222
- ">
223
  <tr>
224
  <th scope="row">
225
  <label for='relevanssi_highlight'><?php esc_html_e( 'Highlight type', 'relevanssi' ); ?></label>
@@ -309,8 +303,6 @@ function relevanssi_excerpts_tab() {
309
  <?php esc_html_e( 'Highlight in titles', 'relevanssi' ); ?>
310
  </th>
311
  <td>
312
- <fieldset>
313
- <legend class="screen-reader-text"><?php esc_html_e( 'Highlight query terms in titles', 'relevanssi' ); ?></legend>
314
  <label for='relevanssi_hilite_title'>
315
  <input type='checkbox' name='relevanssi_hilite_title' id='relevanssi_hilite_title' <?php echo esc_html( $highlight_title ); ?>
316
  <?php
@@ -321,7 +313,6 @@ function relevanssi_excerpts_tab() {
321
  />
322
  <?php esc_html_e( 'Highlight query terms in titles', 'relevanssi' ); ?>
323
  </label>
324
- </fieldset>
325
  <?php // Translators: %1$s is 'the_title()', %2$s is 'relevanssi_the_title()'. ?>
326
  <p class="description"><?php printf( esc_html__( 'Highlights in titles require changes to the search results template. You need to replace %1$s in the search results template with %2$s. For more information, see the contextual help.', 'relevanssi' ), '<code>the_title()</code>', '<code>relevanssi_the_title()</code>' ); ?></p>
327
  </td>
@@ -331,8 +322,6 @@ function relevanssi_excerpts_tab() {
331
  <?php esc_html_e( 'Highlight in documents', 'relevanssi' ); ?>
332
  </th>
333
  <td>
334
- <fieldset>
335
- <legend class="screen-reader-text"><?php esc_html_e( 'Highlight query terms in documents', 'relevanssi' ); ?></legend>
336
  <label for='relevanssi_highlight_docs'>
337
  <input type='checkbox' name='relevanssi_highlight_docs' id='relevanssi_highlight_docs' <?php echo esc_html( $highlight_docs ); ?>
338
  <?php
@@ -343,7 +332,6 @@ function relevanssi_excerpts_tab() {
343
  />
344
  <?php esc_html_e( 'Highlight query terms in documents', 'relevanssi' ); ?>
345
  </label>
346
- </fieldset>
347
  <?php // Translators: %s is 'highlight'. ?>
348
  <p class="description"><?php printf( esc_html__( 'Highlights hits when user opens the post from search results. This requires an extra parameter (%s) to the links from the search results pages, which Relevanssi should add automatically.', 'relevanssi' ), '<code>highlight</code>' ); ?></p>
349
  </td>
@@ -353,8 +341,6 @@ function relevanssi_excerpts_tab() {
353
  <?php esc_html_e( 'Highlight in comments', 'relevanssi' ); ?>
354
  </th>
355
  <td>
356
- <fieldset>
357
- <legend class="screen-reader-text"><?php esc_html_e( 'Highlight query terms in comments', 'relevanssi' ); ?></legend>
358
  <label for='relevanssi_highlight_comments'>
359
  <input type='checkbox' name='relevanssi_highlight_comments' id='relevanssi_highlight_comments' <?php echo esc_html( $highlight_coms ); ?>
360
  <?php
@@ -365,7 +351,6 @@ function relevanssi_excerpts_tab() {
365
  />
366
  <?php esc_html_e( 'Highlight query terms in comments', 'relevanssi' ); ?>
367
  </label>
368
- </fieldset>
369
  <p class="description"><?php esc_html_e( 'Highlights hits in comments when user opens the post from search results.', 'relevanssi' ); ?></p>
370
  </td>
371
  </tr>
@@ -374,8 +359,6 @@ function relevanssi_excerpts_tab() {
374
  <?php esc_html_e( 'Highlighting problems with non-ASCII alphabet?', 'relevanssi' ); ?>
375
  </th>
376
  <td>
377
- <fieldset>
378
- <legend class="screen-reader-text"><?php esc_html_e( 'Uncheck this if you use non-ASCII characters', 'relevanssi' ); ?></legend>
379
  <label for='relevanssi_word_boundaries'>
380
  <input type='checkbox' name='relevanssi_word_boundaries' id='relevanssi_word_boundaries' <?php echo esc_html( $word_boundaries ); ?>
381
  <?php
@@ -386,7 +369,6 @@ function relevanssi_excerpts_tab() {
386
  />
387
  <?php esc_html_e( 'Uncheck this if you use non-ASCII characters', 'relevanssi' ); ?>
388
  </label>
389
- </fieldset>
390
  <p class="description"><?php esc_html_e( "If you use non-ASCII characters (like Cyrillic alphabet) and the highlights don't work, unchecking this option may make the highlights work.", 'relevanssi' ); ?></p>
391
  </td>
392
  </tr>
@@ -400,14 +382,12 @@ function relevanssi_excerpts_tab() {
400
  echo 'relevanssi_disabled';
401
  }
402
  ?>
403
- ">
404
  <tr>
405
  <th scope="row">
406
  <?php esc_html_e( 'Breakdown of search hits in excerpts', 'relevanssi' ); ?>
407
  </th>
408
  <td>
409
- <fieldset>
410
- <legend class="screen-reader-text"><?php esc_html_e( 'Show the breakdown of search hits in the excerpts', 'relevanssi' ); ?></legend>
411
  <label for='relevanssi_show_matches'>
412
  <input type='checkbox' name='relevanssi_show_matches' id='relevanssi_show_matches' <?php echo esc_html( $show_matches ); ?>
413
  <?php
@@ -418,7 +398,6 @@ function relevanssi_excerpts_tab() {
418
  />
419
  <?php esc_html_e( 'Show the breakdown of search hits in the excerpts.', 'relevanssi' ); ?>
420
  </label>
421
- </fieldset>
422
  <p class="description"><?php esc_html_e( 'Requires custom snippets to work.', 'relevanssi' ); ?></p>
423
  </td>
424
  </tr>
83
 
84
  <h2 id="excerpts"><?php esc_html_e( 'Custom excerpts/snippets', 'relevanssi' ); ?></h2>
85
 
86
+ <table class="form-table" role="presentation">
87
  <tr>
88
  <th scope="row">
89
  <?php esc_html_e( 'Custom search result snippets', 'relevanssi' ); ?>
90
  </th>
91
  <td>
 
 
92
  <label >
93
  <input type='checkbox' name='relevanssi_excerpts' id='relevanssi_excerpts' <?php echo esc_html( $excerpts ); ?> />
94
  <?php esc_html_e( 'Create custom search result snippets', 'relevanssi' ); ?>
95
  </label>
 
96
  <p class="description"><?php esc_html_e( 'Only enable this if you actually use the custom excerpts.', 'relevanssi' ); ?></p>
97
  <?php
98
  $theme = wp_get_theme();
168
  <?php esc_html_e( 'Use custom fields for excerpts', 'relevanssi' ); ?>
169
  </th>
170
  <td>
 
 
171
  <label>
172
  <input type='checkbox' name='relevanssi_excerpt_custom_fields' id='relevanssi_excerpt_custom_fields' <?php echo esc_html( $excerpt_custom_fields ); ?>
173
  <?php
178
  />
179
  <?php esc_html_e( 'Use custom field content for building excerpts', 'relevanssi' ); ?>
180
  </label>
 
181
  <p class="description"><?php esc_html_e( 'Use the custom fields setting for indexing for excerpt-making as well. Enabling this option will show custom field content in Relevanssi-generated excerpts.', 'relevanssi' ); ?>
182
  <?php
183
  if ( RELEVANSSI_PREMIUM ) {
213
  echo 'relevanssi_disabled';
214
  }
215
  ?>
216
+ " role="presentation">
217
  <tr>
218
  <th scope="row">
219
  <label for='relevanssi_highlight'><?php esc_html_e( 'Highlight type', 'relevanssi' ); ?></label>
303
  <?php esc_html_e( 'Highlight in titles', 'relevanssi' ); ?>
304
  </th>
305
  <td>
 
 
306
  <label for='relevanssi_hilite_title'>
307
  <input type='checkbox' name='relevanssi_hilite_title' id='relevanssi_hilite_title' <?php echo esc_html( $highlight_title ); ?>
308
  <?php
313
  />
314
  <?php esc_html_e( 'Highlight query terms in titles', 'relevanssi' ); ?>
315
  </label>
 
316
  <?php // Translators: %1$s is 'the_title()', %2$s is 'relevanssi_the_title()'. ?>
317
  <p class="description"><?php printf( esc_html__( 'Highlights in titles require changes to the search results template. You need to replace %1$s in the search results template with %2$s. For more information, see the contextual help.', 'relevanssi' ), '<code>the_title()</code>', '<code>relevanssi_the_title()</code>' ); ?></p>
318
  </td>
322
  <?php esc_html_e( 'Highlight in documents', 'relevanssi' ); ?>
323
  </th>
324
  <td>
 
 
325
  <label for='relevanssi_highlight_docs'>
326
  <input type='checkbox' name='relevanssi_highlight_docs' id='relevanssi_highlight_docs' <?php echo esc_html( $highlight_docs ); ?>
327
  <?php
332
  />
333
  <?php esc_html_e( 'Highlight query terms in documents', 'relevanssi' ); ?>
334
  </label>
 
335
  <?php // Translators: %s is 'highlight'. ?>
336
  <p class="description"><?php printf( esc_html__( 'Highlights hits when user opens the post from search results. This requires an extra parameter (%s) to the links from the search results pages, which Relevanssi should add automatically.', 'relevanssi' ), '<code>highlight</code>' ); ?></p>
337
  </td>
341
  <?php esc_html_e( 'Highlight in comments', 'relevanssi' ); ?>
342
  </th>
343
  <td>
 
 
344
  <label for='relevanssi_highlight_comments'>
345
  <input type='checkbox' name='relevanssi_highlight_comments' id='relevanssi_highlight_comments' <?php echo esc_html( $highlight_coms ); ?>
346
  <?php
351
  />
352
  <?php esc_html_e( 'Highlight query terms in comments', 'relevanssi' ); ?>
353
  </label>
 
354
  <p class="description"><?php esc_html_e( 'Highlights hits in comments when user opens the post from search results.', 'relevanssi' ); ?></p>
355
  </td>
356
  </tr>
359
  <?php esc_html_e( 'Highlighting problems with non-ASCII alphabet?', 'relevanssi' ); ?>
360
  </th>
361
  <td>
 
 
362
  <label for='relevanssi_word_boundaries'>
363
  <input type='checkbox' name='relevanssi_word_boundaries' id='relevanssi_word_boundaries' <?php echo esc_html( $word_boundaries ); ?>
364
  <?php
369
  />
370
  <?php esc_html_e( 'Uncheck this if you use non-ASCII characters', 'relevanssi' ); ?>
371
  </label>
 
372
  <p class="description"><?php esc_html_e( "If you use non-ASCII characters (like Cyrillic alphabet) and the highlights don't work, unchecking this option may make the highlights work.", 'relevanssi' ); ?></p>
373
  </td>
374
  </tr>
382
  echo 'relevanssi_disabled';
383
  }
384
  ?>
385
+ " role="presentation">
386
  <tr>
387
  <th scope="row">
388
  <?php esc_html_e( 'Breakdown of search hits in excerpts', 'relevanssi' ); ?>
389
  </th>
390
  <td>
 
 
391
  <label for='relevanssi_show_matches'>
392
  <input type='checkbox' name='relevanssi_show_matches' id='relevanssi_show_matches' <?php echo esc_html( $show_matches ); ?>
393
  <?php
398
  />
399
  <?php esc_html_e( 'Show the breakdown of search hits in the excerpts.', 'relevanssi' ); ?>
400
  </label>
 
401
  <p class="description"><?php esc_html_e( 'Requires custom snippets to work.', 'relevanssi' ); ?></p>
402
  </td>
403
  </tr>
lib/tabs/indexing-tab.php CHANGED
@@ -25,6 +25,7 @@ function relevanssi_indexing_tab() {
25
  $index_fields = get_option( 'relevanssi_index_fields' );
26
  $index_author = get_option( 'relevanssi_index_author' );
27
  $index_excerpt = get_option( 'relevanssi_index_excerpt' );
 
28
  $expand_shortcodes = get_option( 'relevanssi_expand_shortcodes' );
29
  $punctuation = get_option( 'relevanssi_punctuation' );
30
  $min_word_length = get_option( 'relevanssi_min_word_length' );
@@ -39,6 +40,7 @@ function relevanssi_indexing_tab() {
39
  $expand_shortcodes = relevanssi_check( $expand_shortcodes );
40
  $index_author = relevanssi_check( $index_author );
41
  $index_excerpt = relevanssi_check( $index_excerpt );
 
42
  $index_comments_all = relevanssi_select( $index_comments, 'all' );
43
  $index_comments_normal = relevanssi_select( $index_comments, 'normal' );
44
  $index_comments_none = relevanssi_select( $index_comments, 'none' );
@@ -99,7 +101,7 @@ function relevanssi_indexing_tab() {
99
  ?>
100
  <div id="indexing_tab">
101
 
102
- <table class="form-table">
103
  <tr>
104
  <td scope="row">
105
  <input type='submit' name='submit' value='<?php esc_attr_e( 'Save the options', 'relevanssi' ); ?>' class='button button-primary' /><br /><br />
@@ -154,19 +156,21 @@ function relevanssi_indexing_tab() {
154
 
155
  <p><?php esc_html_e( 'Any changes to the settings on this page require reindexing before they take effect.', 'relevanssi' ); ?></p>
156
 
157
- <table class="form-table">
158
  <tr>
159
  <th scope="row"><?php esc_html_e( 'Post types', 'relevanssi' ); ?></th>
160
  <td>
161
 
162
- <table class="widefat" id="index_post_types_table">
163
- <thead>
164
- <tr>
165
- <th><?php esc_html_e( 'Type', 'relevanssi' ); ?></th>
166
- <th><?php esc_html_e( 'Index', 'relevanssi' ); ?></th>
167
- <th><?php esc_html_e( 'Excluded from search?', 'relevanssi' ); ?></th>
168
- </tr>
169
- </thead>
 
 
170
  <?php
171
  $pt_1 = get_post_types( array( 'exclude_from_search' => '0' ) );
172
  $pt_2 = get_post_types( array( 'exclude_from_search' => false ) );
@@ -180,39 +184,71 @@ function relevanssi_indexing_tab() {
180
  if ( in_array( $type, $index_post_types, true ) ) {
181
  $checked = 'checked="checked"';
182
  }
183
- $label = sprintf( '%s', $type );
 
 
184
  $excluded_from_search = __( 'yes', 'relevanssi' );
 
 
185
  if ( in_array( $type, $public_types, true ) ) {
186
  $excluded_from_search = __( 'no', 'relevanssi' );
 
 
187
  }
188
  $name_id = 'relevanssi_index_type_' . $type;
189
  printf(
190
- '<tr><td><label for="%2$s">%1$s</label></td><td><input type="checkbox" name="%2$s" id="%2$s" %3$s /></td><td>%4$s</td></tr>',
 
 
 
 
 
191
  esc_html( $label ),
192
  esc_attr( $name_id ),
193
  esc_html( $checked ),
194
- esc_html( $excluded_from_search )
 
195
  );
196
  }
197
  ?>
198
- <tr style="display:none">
199
- <td>
200
- <label for="relevanssi_index_type_bogus">Helper control field to make sure settings are saved if no post types are selected.</label>
201
- </td>
202
- <td>
203
- <input type='checkbox' name='relevanssi_index_type_bogus' id='relevanssi_index_type_bogus' checked="checked" />
204
- </td>
205
- <td>
206
- This is our little secret, just for you and me
207
- </td>
208
- </tr>
209
- </table>
210
- <?php // Translators: %1$s is 'attachment', %2$s opens the link, %3$s closes it. ?>
211
- <p class="description"><?php printf( esc_html__( '%1$s includes all attachment types. If you want to index only some attachments, see %2$sControlling attachment types in the Knowledge base%3$s.', 'relevanssi' ), '<code>attachment</code>', '<a href="https://www.relevanssi.com/knowledge-base/controlling-attachment-types-index/">', '</a>' ); ?></p>
212
  <p class="description"><?php esc_html_e( "If you want to index a post type that's marked 'Excluded from search', you can do that without worrying about it – but you need to uncheck the 'Respect exclude_from_search' setting from the Searching tab.", 'relevanssi' ); ?></p>
213
  </td>
214
  </tr>
215
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  <tr>
217
  <th scope="row">
218
  <?php esc_html_e( 'Taxonomies', 'relevanssi' ); ?>
@@ -238,19 +274,33 @@ function relevanssi_indexing_tab() {
238
  if ( in_array( $taxonomy->name, $index_taxonomies_list, true ) ) {
239
  $checked = 'checked="checked"';
240
  }
241
- $label = sprintf( '%s', $taxonomy->name );
242
- $public = __( 'no', 'relevanssi' );
 
 
 
 
243
  if ( $taxonomy->public ) {
244
  $public = __( 'yes', 'relevanssi' );
 
 
245
  }
 
246
  $name_id = 'relevanssi_index_taxonomy_' . $taxonomy->name;
247
  printf(
248
- '<tr><td><label for="%2$s">%1$s</label></td><td><input type="checkbox" name="%2$s" id="%2$s" %3$s /></td><td>%4$s</td></tr>',
249
- esc_html( $label ),
 
 
 
 
 
250
  esc_attr( $name_id ),
251
  esc_html( $checked ),
252
- esc_html( $public )
 
253
  );
 
254
  }
255
  ?>
256
  </table>
@@ -308,7 +358,7 @@ function relevanssi_indexing_tab() {
308
  }
309
  ?>
310
  >
311
- <label for="relevanssi_index_fields" class="screen-reader-text"><?php esc_html__( 'Custom fields to index', 'relevanssi' ); ?></label>
312
  <input type='text' name='relevanssi_index_fields' id='relevanssi_index_fields' size='60' value='<?php echo esc_attr( $index_fields ); ?>' />
313
  <p class="description"><?php esc_html_e( "Enter a comma-separated list of custom fields to include in the index. With Relevanssi Premium, you can also use 'fieldname_%_subfieldname' notation for ACF repeater fields.", 'relevanssi' ); ?></p>
314
  <p class="description"><?php esc_html_e( "You can use 'relevanssi_index_custom_fields' filter hook to adjust which custom fields are indexed.", 'relevanssi' ); ?></p>
@@ -325,14 +375,11 @@ function relevanssi_indexing_tab() {
325
  <?php esc_html_e( 'Author display names', 'relevanssi' ); ?>
326
  </th>
327
  <td>
328
- <fieldset>
329
- <legend class="screen-reader-text"><?php esc_html_e( 'Index the post author display name', 'relevanssi' ); ?></legend>
330
  <label for='relevanssi_index_author'>
331
  <input type='checkbox' name='relevanssi_index_author' id='relevanssi_index_author' <?php echo esc_html( $index_author ); ?> />
332
  <?php esc_html_e( 'Index the post author display name', 'relevanssi' ); ?>
333
  </label>
334
  <p class="description"><?php esc_html_e( 'Searching for the post author display name will return posts by that author.', 'relevanssi' ); ?></p>
335
- </fieldset>
336
  </td>
337
  </tr>
338
 
@@ -341,8 +388,6 @@ function relevanssi_indexing_tab() {
341
  <?php esc_html_e( 'Excerpts', 'relevanssi' ); ?>
342
  </th>
343
  <td>
344
- <fieldset>
345
- <legend class="screen-reader-text"><?php esc_html_e( 'Index the post excerpt', 'relevanssi' ); ?></legend>
346
  <label for='relevanssi_index_excerpt'>
347
  <input type='checkbox' name='relevanssi_index_excerpt' id='relevanssi_index_excerpt' <?php echo esc_html( $index_excerpt ); ?> />
348
  <?php esc_html_e( 'Index the post excerpt', 'relevanssi' ); ?>
@@ -351,7 +396,6 @@ function relevanssi_indexing_tab() {
351
  <?php if ( is_plugin_active( 'woocommerce/woocommerce.php' ) ) : ?>
352
  <p class="description"><?php esc_html_e( "WooCommerce stores the product short description in the excerpt, so it's a good idea to index excerpts.", 'relevanssi' ); ?></p>
353
  <?php endif; ?>
354
- </fieldset>
355
  </td>
356
  </tr>
357
 
@@ -359,14 +403,12 @@ function relevanssi_indexing_tab() {
359
 
360
  <h2><?php esc_html_e( 'Shortcodes', 'relevanssi' ); ?></h2>
361
 
362
- <table class="form-table">
363
  <tr>
364
  <th scope="row">
365
  <?php esc_html_e( 'Expand shortcodes', 'relevanssi' ); ?>
366
  </th>
367
  <td>
368
- <fieldset>
369
- <legend class="screen-reader-text"><?php esc_html_e( 'Index the post excerpt', 'relevanssi' ); ?></legend>
370
  <label for='relevanssi_expand_shortcodes'>
371
  <input type='checkbox' name='relevanssi_expand_shortcodes' id='relevanssi_expand_shortcodes' <?php echo esc_html( $expand_shortcodes ); ?> />
372
  <?php esc_html_e( 'Expand shortcodes when indexing', 'relevanssi' ); ?>
@@ -376,7 +418,6 @@ function relevanssi_indexing_tab() {
376
  <?php endif; ?>
377
  <p class="description"><?php esc_html_e( 'If checked, Relevanssi will expand shortcodes in post content before indexing. Otherwise shortcodes will be stripped.', 'relevanssi' ); ?></p>
378
  <p class="description"><?php esc_html_e( 'If you use shortcodes to include dynamic content, Relevanssi will not keep the index updated, the index will reflect the status of the shortcode content at the moment of indexing.', 'relevanssi' ); ?></p>
379
- </fieldset>
380
  </td>
381
  </tr>
382
 
@@ -410,7 +451,7 @@ function relevanssi_indexing_tab() {
410
 
411
  <p><button type="button" id="show_advanced_indexing"><?php esc_html_e( 'Show advanced settings', 'relevanssi' ); ?></button></p>
412
 
413
- <table class="form-table screen-reader-text" id="advanced_indexing">
414
  <tr>
415
  <th scope="row">
416
  <label for='relevanssi_min_word_length'><?php esc_html_e( 'Minimum word length', 'relevanssi' ); ?></label>
25
  $index_fields = get_option( 'relevanssi_index_fields' );
26
  $index_author = get_option( 'relevanssi_index_author' );
27
  $index_excerpt = get_option( 'relevanssi_index_excerpt' );
28
+ $index_image_files = get_option( 'relevanssi_index_image_files' );
29
  $expand_shortcodes = get_option( 'relevanssi_expand_shortcodes' );
30
  $punctuation = get_option( 'relevanssi_punctuation' );
31
  $min_word_length = get_option( 'relevanssi_min_word_length' );
40
  $expand_shortcodes = relevanssi_check( $expand_shortcodes );
41
  $index_author = relevanssi_check( $index_author );
42
  $index_excerpt = relevanssi_check( $index_excerpt );
43
+ $index_image_files = relevanssi_check( $index_image_files );
44
  $index_comments_all = relevanssi_select( $index_comments, 'all' );
45
  $index_comments_normal = relevanssi_select( $index_comments, 'normal' );
46
  $index_comments_none = relevanssi_select( $index_comments, 'none' );
101
  ?>
102
  <div id="indexing_tab">
103
 
104
+ <table class="form-table" role="presentation">
105
  <tr>
106
  <td scope="row">
107
  <input type='submit' name='submit' value='<?php esc_attr_e( 'Save the options', 'relevanssi' ); ?>' class='button button-primary' /><br /><br />
156
 
157
  <p><?php esc_html_e( 'Any changes to the settings on this page require reindexing before they take effect.', 'relevanssi' ); ?></p>
158
 
159
+ <table class="form-table" role="presentation">
160
  <tr>
161
  <th scope="row"><?php esc_html_e( 'Post types', 'relevanssi' ); ?></th>
162
  <td>
163
 
164
+ <fieldset>
165
+ <legend class="screen-reader-text"><?php esc_html_e( 'Post types to index', 'relevanssi' ); ?></legend>
166
+ <table class="widefat" id="index_post_types_table">
167
+ <thead>
168
+ <tr>
169
+ <th><?php esc_html_e( 'Type', 'relevanssi' ); ?></th>
170
+ <th><?php esc_html_e( 'Index', 'relevanssi' ); ?></th>
171
+ <th><?php esc_html_e( 'Excluded from search?', 'relevanssi' ); ?></th>
172
+ </tr>
173
+ </thead>
174
  <?php
175
  $pt_1 = get_post_types( array( 'exclude_from_search' => '0' ) );
176
  $pt_2 = get_post_types( array( 'exclude_from_search' => false ) );
184
  if ( in_array( $type, $index_post_types, true ) ) {
185
  $checked = 'checked="checked"';
186
  }
187
+ // Translators: %s is the post type name.
188
+ $screen_reader_label = sprintf( __( 'Index post type %s', 'relevanssi' ), $type );
189
+ $label = $type;
190
  $excluded_from_search = __( 'yes', 'relevanssi' );
191
+ // Translators: %s is the post type name.
192
+ $screen_reader_exclude = sprintf( __( 'Post type %s is excluded from search', 'relevanssi' ), $type );
193
  if ( in_array( $type, $public_types, true ) ) {
194
  $excluded_from_search = __( 'no', 'relevanssi' );
195
+ // Translators: %s is the post type name.
196
+ $screen_reader_exclude = sprintf( __( 'Post type %s can be searched', 'relevanssi' ), $type );
197
  }
198
  $name_id = 'relevanssi_index_type_' . $type;
199
  printf(
200
+ '<tr>
201
+ <th scope="row"><label class="screen-reader-text" for="%3$s">%1$s</label> %2$s</th>
202
+ <td><input type="checkbox" name="%3$s" id="%3$s" %4$s /></td>
203
+ <td><span aria-hidden="true">%5$s</span><span class="screen-reader-text">%6$s</span></td>
204
+ </tr>',
205
+ esc_html( $screen_reader_label ),
206
  esc_html( $label ),
207
  esc_attr( $name_id ),
208
  esc_html( $checked ),
209
+ esc_html( $excluded_from_search ),
210
+ esc_html( $screen_reader_exclude )
211
  );
212
  }
213
  ?>
214
+ <tr style="display:none">
215
+ <td>
216
+ <label for="relevanssi_index_type_bogus">Helper control field to make sure settings are saved if no post types are selected.</label>
217
+ </td>
218
+ <td>
219
+ <input type='checkbox' name='relevanssi_index_type_bogus' id='relevanssi_index_type_bogus' checked="checked" />
220
+ </td>
221
+ <td>
222
+ This is our little secret, just for you and me
223
+ </td>
224
+ </tr>
225
+ </table>
226
+ </fieldset>
 
227
  <p class="description"><?php esc_html_e( "If you want to index a post type that's marked 'Excluded from search', you can do that without worrying about it – but you need to uncheck the 'Respect exclude_from_search' setting from the Searching tab.", 'relevanssi' ); ?></p>
228
  </td>
229
  </tr>
230
 
231
+ <tr id="row_index_image_files"
232
+ <?php
233
+ if ( ! in_array( 'attachment', $index_post_types, true ) ) {
234
+ echo 'style="display: none"';
235
+ }
236
+ ?>
237
+ >
238
+ <th scope="row">
239
+ <?php esc_html_e( 'Index image files', 'relevanssi' ); ?>
240
+ </th>
241
+ <td>
242
+ <label for='relevanssi_index_image_files'>
243
+ <input type='checkbox' name='relevanssi_index_image_files' id='relevanssi_index_image_files' <?php echo esc_attr( $index_image_files ); ?> />
244
+ <?php esc_html_e( 'Index image attachments', 'relevanssi' ); ?>
245
+ </label>
246
+ <p class="description"><?php esc_html_e( 'If this option is enabled, Relevanssi will include image attachments in the index. If the option is disabled, only other attachment types are included.', 'relevanssi' ); ?></p>
247
+ <?php // Translators: %1$s opens the link, %2$s closes it. ?>
248
+ <p class="description"><?php printf( esc_html__( 'For more detailed control over the attachment type indexing, see %1$sControlling attachment types in the Knowledge base%2$s.', 'relevanssi' ), '<a href="https://www.relevanssi.com/knowledge-base/controlling-attachment-types-index/">', '</a>' ); ?></p>
249
+ </td>
250
+ </tr>
251
+
252
  <tr>
253
  <th scope="row">
254
  <?php esc_html_e( 'Taxonomies', 'relevanssi' ); ?>
274
  if ( in_array( $taxonomy->name, $index_taxonomies_list, true ) ) {
275
  $checked = 'checked="checked"';
276
  }
277
+
278
+ // Translators: %s is the post type name.
279
+ $screen_reader_label = sprintf( __( 'Index taxonomy %s', 'relevanssi' ), $taxonomy->name );
280
+ $public = __( 'no', 'relevanssi' );
281
+ // Translators: %s is the post type name.
282
+ $screen_reader_public = sprintf( __( 'Taxonomy %s is not public', 'relevanssi' ), $taxonomy->name );
283
  if ( $taxonomy->public ) {
284
  $public = __( 'yes', 'relevanssi' );
285
+ // Translators: %s is the post type name.
286
+ $screen_reader_public = sprintf( __( 'Taxonomy %s is public', 'relevanssi' ), $taxonomy->name );
287
  }
288
+
289
  $name_id = 'relevanssi_index_taxonomy_' . $taxonomy->name;
290
  printf(
291
+ '<tr>
292
+ <th scope="row"><label class="screen-reader-text" for="%3$s">%1$s</label> %2$s</th>
293
+ <td><input type="checkbox" name="%3$s" id="%3$s" %4$s /></td>
294
+ <td><span aria-hidden="true">%5$s</span><span class="screen-reader-text">%6$s</span></td>
295
+ </tr>',
296
+ esc_html( $screen_reader_label ),
297
+ esc_html( $taxonomy->name ),
298
  esc_attr( $name_id ),
299
  esc_html( $checked ),
300
+ esc_html( $public ),
301
+ esc_html( $screen_reader_public )
302
  );
303
+
304
  }
305
  ?>
306
  </table>
358
  }
359
  ?>
360
  >
361
+ <label for="relevanssi_index_fields" class="screen-reader-text"><?php esc_html_e( 'Custom fields to index', 'relevanssi' ); ?></label>
362
  <input type='text' name='relevanssi_index_fields' id='relevanssi_index_fields' size='60' value='<?php echo esc_attr( $index_fields ); ?>' />
363
  <p class="description"><?php esc_html_e( "Enter a comma-separated list of custom fields to include in the index. With Relevanssi Premium, you can also use 'fieldname_%_subfieldname' notation for ACF repeater fields.", 'relevanssi' ); ?></p>
364
  <p class="description"><?php esc_html_e( "You can use 'relevanssi_index_custom_fields' filter hook to adjust which custom fields are indexed.", 'relevanssi' ); ?></p>
375
  <?php esc_html_e( 'Author display names', 'relevanssi' ); ?>
376
  </th>
377
  <td>
 
 
378
  <label for='relevanssi_index_author'>
379
  <input type='checkbox' name='relevanssi_index_author' id='relevanssi_index_author' <?php echo esc_html( $index_author ); ?> />
380
  <?php esc_html_e( 'Index the post author display name', 'relevanssi' ); ?>
381
  </label>
382
  <p class="description"><?php esc_html_e( 'Searching for the post author display name will return posts by that author.', 'relevanssi' ); ?></p>
 
383
  </td>
384
  </tr>
385
 
388
  <?php esc_html_e( 'Excerpts', 'relevanssi' ); ?>
389
  </th>
390
  <td>
 
 
391
  <label for='relevanssi_index_excerpt'>
392
  <input type='checkbox' name='relevanssi_index_excerpt' id='relevanssi_index_excerpt' <?php echo esc_html( $index_excerpt ); ?> />
393
  <?php esc_html_e( 'Index the post excerpt', 'relevanssi' ); ?>
396
  <?php if ( is_plugin_active( 'woocommerce/woocommerce.php' ) ) : ?>
397
  <p class="description"><?php esc_html_e( "WooCommerce stores the product short description in the excerpt, so it's a good idea to index excerpts.", 'relevanssi' ); ?></p>
398
  <?php endif; ?>
 
399
  </td>
400
  </tr>
401
 
403
 
404
  <h2><?php esc_html_e( 'Shortcodes', 'relevanssi' ); ?></h2>
405
 
406
+ <table class="form-table" role="presentation">
407
  <tr>
408
  <th scope="row">
409
  <?php esc_html_e( 'Expand shortcodes', 'relevanssi' ); ?>
410
  </th>
411
  <td>
 
 
412
  <label for='relevanssi_expand_shortcodes'>
413
  <input type='checkbox' name='relevanssi_expand_shortcodes' id='relevanssi_expand_shortcodes' <?php echo esc_html( $expand_shortcodes ); ?> />
414
  <?php esc_html_e( 'Expand shortcodes when indexing', 'relevanssi' ); ?>
418
  <?php endif; ?>
419
  <p class="description"><?php esc_html_e( 'If checked, Relevanssi will expand shortcodes in post content before indexing. Otherwise shortcodes will be stripped.', 'relevanssi' ); ?></p>
420
  <p class="description"><?php esc_html_e( 'If you use shortcodes to include dynamic content, Relevanssi will not keep the index updated, the index will reflect the status of the shortcode content at the moment of indexing.', 'relevanssi' ); ?></p>
 
421
  </td>
422
  </tr>
423
 
451
 
452
  <p><button type="button" id="show_advanced_indexing"><?php esc_html_e( 'Show advanced settings', 'relevanssi' ); ?></button></p>
453
 
454
+ <table class="form-table screen-reader-text" id="advanced_indexing" role="presentation">
455
  <tr>
456
  <th scope="row">
457
  <label for='relevanssi_min_word_length'><?php esc_html_e( 'Minimum word length', 'relevanssi' ); ?></label>
lib/tabs/logging-tab.php CHANGED
@@ -27,7 +27,7 @@ function relevanssi_logging_tab() {
27
  $trim_logs = get_option( 'relevanssi_trim_logs' );
28
 
29
  ?>
30
- <table class="form-table">
31
  <tr>
32
  <th scope="row">
33
  <?php esc_html_e( 'Enable logs', 'relevanssi' ); ?>
27
  $trim_logs = get_option( 'relevanssi_trim_logs' );
28
 
29
  ?>
30
+ <table class="form-table" role="presentation">
31
  <tr>
32
  <th scope="row">
33
  <?php esc_html_e( 'Enable logs', 'relevanssi' ); ?>
lib/tabs/overview-tab.php CHANGED
@@ -21,7 +21,7 @@ function relevanssi_overview_tab() {
21
  ?>
22
  <h2><?php esc_html_e( 'Welcome to Relevanssi!', 'relevanssi' ); ?></h2>
23
 
24
- <table class="form-table">
25
 
26
  <?php
27
  if ( ! is_plugin_active_for_network( plugin_basename( $relevanssi_variables['file'] ) ) && function_exists( 'relevanssi_form_api_key' ) ) {
@@ -43,9 +43,9 @@ function relevanssi_overview_tab() {
43
  <?php // Translators: %1$s opens the link, %2$s is the anchor text, %3$s closes the link. ?>
44
  <li><p><?php printf( esc_html__( 'Now, you need an index. Head over to the %1$s%2$s%3$s tab to set up the basic indexing options and to build the index.', 'relevanssi' ), "<a href='" . esc_attr( $this_page ) . "&amp;tab=indexing'>", esc_html__( 'Indexing', 'relevanssi' ), '</a>' ); ?></p>
45
  <p><?php esc_html_e( 'You need to check at least the following options:', 'relevanssi' ); ?><br />
46
- <?php esc_html_e( 'Make sure the post types you want to include in the index are indexed.', 'relevanssi' ); ?><br />
47
  <?php // Translators: %s is '_sku'. ?>
48
- <?php printf( esc_html__( 'Do you use custom fields to store content you want included? If so, add those too. WooCommerce user? You probably want to include %s.', 'relevanssi' ), '<code>_sku</code>' ); ?></p>
49
  <p><?php esc_html_e( "Then just save the options and build the index. First time you have to do it manually, but after that, it's fully automatic: all changes are reflected in the index without reindexing. (That said, it's a good idea to rebuild the index once a year.)", 'relevanssi' ); ?></p>
50
  </li>
51
  <?php else : ?>
21
  ?>
22
  <h2><?php esc_html_e( 'Welcome to Relevanssi!', 'relevanssi' ); ?></h2>
23
 
24
+ <table class="form-table" role="presentation">
25
 
26
  <?php
27
  if ( ! is_plugin_active_for_network( plugin_basename( $relevanssi_variables['file'] ) ) && function_exists( 'relevanssi_form_api_key' ) ) {
43
  <?php // Translators: %1$s opens the link, %2$s is the anchor text, %3$s closes the link. ?>
44
  <li><p><?php printf( esc_html__( 'Now, you need an index. Head over to the %1$s%2$s%3$s tab to set up the basic indexing options and to build the index.', 'relevanssi' ), "<a href='" . esc_attr( $this_page ) . "&amp;tab=indexing'>", esc_html__( 'Indexing', 'relevanssi' ), '</a>' ); ?></p>
45
  <p><?php esc_html_e( 'You need to check at least the following options:', 'relevanssi' ); ?><br />
46
+ &ndash; <?php esc_html_e( 'Make sure the post types you want to include in the index are indexed.', 'relevanssi' ); ?><br />
47
  <?php // Translators: %s is '_sku'. ?>
48
+ &ndash; <?php printf( esc_html__( 'Do you use custom fields to store content you want included? If so, add those too. WooCommerce user? You probably want to include %s.', 'relevanssi' ), '<code>_sku</code>' ); ?></p>
49
  <p><?php esc_html_e( "Then just save the options and build the index. First time you have to do it manually, but after that, it's fully automatic: all changes are reflected in the index without reindexing. (That said, it's a good idea to rebuild the index once a year.)", 'relevanssi' ); ?></p>
50
  </li>
51
  <?php else : ?>
lib/tabs/search-page.php CHANGED
@@ -18,7 +18,7 @@ function relevanssi_search_tab() {
18
  <p><?php esc_html_e( 'You can use this search to perform Relevanssi searches without any restrictions from WordPress. You can search all post types here.', 'relevanssi' ); ?></p>
19
 
20
  <form action="" method="get">
21
- <table class="form-table">
22
  <tr>
23
  <th scope="row">
24
  <label for='s'><?php esc_html_e( 'Search terms', 'relevanssi' ); ?></label>
18
  <p><?php esc_html_e( 'You can use this search to perform Relevanssi searches without any restrictions from WordPress. You can search all post types here.', 'relevanssi' ); ?></p>
19
 
20
  <form action="" method="get">
21
+ <table class="form-table" role="presentation">
22
  <tr>
23
  <th scope="row">
24
  <label for='s'><?php esc_html_e( 'Search terms', 'relevanssi' ); ?></label>
lib/tabs/searching-tab.php CHANGED
@@ -60,7 +60,7 @@ function relevanssi_searching_tab() {
60
  $docs_count = $wpdb->get_var( 'SELECT COUNT(DISTINCT doc) FROM ' . $relevanssi_variables['relevanssi_table'] . ' WHERE doc != -1' ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
61
  ?>
62
 
63
- <table class="form-table">
64
  <tr>
65
  <th scope="row">
66
  <label for='relevanssi_implicit_operator'><?php esc_html_e( 'Default operator', 'relevanssi' ); ?></label>
@@ -81,7 +81,7 @@ function relevanssi_searching_tab() {
81
  </tr>
82
  <tr id="orfallback" class='<?php echo esc_attr( $orfallback_visibility ); ?>'>
83
  <th scope="row">
84
- <label for='relevanssi_disable_or_fallback'><?php esc_html_e( 'Fallback to OR', 'relevanssi' ); ?></label>
85
  </th>
86
  <td>
87
  <fieldset>
60
  $docs_count = $wpdb->get_var( 'SELECT COUNT(DISTINCT doc) FROM ' . $relevanssi_variables['relevanssi_table'] . ' WHERE doc != -1' ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
61
  ?>
62
 
63
+ <table class="form-table" role="presentation">
64
  <tr>
65
  <th scope="row">
66
  <label for='relevanssi_implicit_operator'><?php esc_html_e( 'Default operator', 'relevanssi' ); ?></label>
81
  </tr>
82
  <tr id="orfallback" class='<?php echo esc_attr( $orfallback_visibility ); ?>'>
83
  <th scope="row">
84
+ <?php esc_html_e( 'Fallback to OR', 'relevanssi' ); ?>
85
  </th>
86
  <td>
87
  <fieldset>
lib/tabs/stopwords-tab.php CHANGED
@@ -49,16 +49,11 @@ function relevanssi_stopwords_tab() {
49
  * Displays a list of stopwords.
50
  *
51
  * Displays the list of stopwords and gives the controls for adding new stopwords.
52
- *
53
- * @global object $wpdb The WP database interface.
54
- * @global array $relevanssi_variables The global Relevanssi variables array.
55
  */
56
  function relevanssi_show_stopwords() {
57
- global $wpdb, $relevanssi_variables;
58
-
59
  printf( '<p>%s</p>', esc_html__( 'Enter a word here to add it to the list of stopwords. The word will automatically be removed from the index, so re-indexing is not necessary. You can enter many words at the same time, separate words with commas.', 'relevanssi' ) );
60
  ?>
61
- <table class="form-table">
62
  <tr>
63
  <th scope="row">
64
  <label for="addstopword"><p><?php esc_html_e( 'Stopword(s) to add', 'relevanssi' ); ?>
@@ -71,25 +66,27 @@ function relevanssi_show_stopwords() {
71
  </table>
72
  <p><?php esc_html_e( "Here's a list of stopwords in the database. Click a word to remove it from stopwords. Removing stopwords won't automatically return them to index, so you need to re-index all posts after removing stopwords to get those words back to index.", 'relevanssi' ); ?></p>
73
 
74
- <table class="form-table">
75
  <tr>
76
  <th scope="row">
77
  <?php esc_html_e( 'Current stopwords', 'relevanssi' ); ?>
78
  </th>
79
  <td>
 
80
  <?php
81
- echo '<ul>';
82
- $results = $wpdb->get_results( 'SELECT * FROM ' . $relevanssi_variables['stopword_table'] ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
83
- $exportlist = array();
84
- foreach ( $results as $stopword ) {
85
- $sw = stripslashes( $stopword->stopword );
86
- printf( '<li style="display: inline;"><input type="submit" name="removestopword" value="%s"/></li>', esc_attr( $sw ) );
87
- array_push( $exportlist, $sw );
88
- }
89
- echo '</ul>';
90
 
91
- $exportlist = htmlspecialchars( implode( ', ', $exportlist ) );
92
  ?>
 
93
  <p><input type="submit" id="removeallstopwords" name="removeallstopwords" value="<?php esc_attr_e( 'Remove all stopwords', 'relevanssi' ); ?>" class='button' /></p>
94
  </td>
95
  </tr>
49
  * Displays a list of stopwords.
50
  *
51
  * Displays the list of stopwords and gives the controls for adding new stopwords.
 
 
 
52
  */
53
  function relevanssi_show_stopwords() {
 
 
54
  printf( '<p>%s</p>', esc_html__( 'Enter a word here to add it to the list of stopwords. The word will automatically be removed from the index, so re-indexing is not necessary. You can enter many words at the same time, separate words with commas.', 'relevanssi' ) );
55
  ?>
56
+ <table class="form-table" role="presentation">
57
  <tr>
58
  <th scope="row">
59
  <label for="addstopword"><p><?php esc_html_e( 'Stopword(s) to add', 'relevanssi' ); ?>
66
  </table>
67
  <p><?php esc_html_e( "Here's a list of stopwords in the database. Click a word to remove it from stopwords. Removing stopwords won't automatically return them to index, so you need to re-index all posts after removing stopwords to get those words back to index.", 'relevanssi' ); ?></p>
68
 
69
+ <table class="form-table" role="presentation">
70
  <tr>
71
  <th scope="row">
72
  <?php esc_html_e( 'Current stopwords', 'relevanssi' ); ?>
73
  </th>
74
  <td>
75
+ <ul>
76
  <?php
77
+ $stopword_list = get_option( 'relevanssi_stopwords', '' );
78
+ $stopword_array = array_map( 'stripslashes', explode( ',', $stopword_list ) );
79
+ sort( $stopword_array );
80
+ array_walk(
81
+ $stopword_array,
82
+ function ( $term ) {
83
+ printf( '<li style="display: inline;"><input type="submit" name="removestopword" value="%s"/></li>', esc_attr( $term ) );
84
+ }
85
+ );
86
 
87
+ $exportlist = htmlspecialchars( str_replace( ',', ', ', $stopword_list ) );
88
  ?>
89
+ </ul>
90
  <p><input type="submit" id="removeallstopwords" name="removeallstopwords" value="<?php esc_attr_e( 'Remove all stopwords', 'relevanssi' ); ?>" class='button' /></p>
91
  </td>
92
  </tr>
lib/tabs/synonyms-tab.php CHANGED
@@ -24,7 +24,7 @@ function relevanssi_synonyms_tab() {
24
  ?>
25
  <h3 id="synonyms"><?php esc_html_e( 'Synonyms', 'relevanssi' ); ?></h3>
26
 
27
- <table class="form-table">
28
  <tr>
29
  <th scope="row">
30
  <label for="relevanssi_synonyms"><?php esc_html_e( 'Synonyms', 'relevanssi' ); ?></label>
24
  ?>
25
  <h3 id="synonyms"><?php esc_html_e( 'Synonyms', 'relevanssi' ); ?></h3>
26
 
27
+ <table class="form-table" role="presentation">
28
  <tr>
29
  <th scope="row">
30
  <label for="relevanssi_synonyms"><?php esc_html_e( 'Synonyms', 'relevanssi' ); ?></label>
lib/uninstall.php CHANGED
@@ -86,6 +86,7 @@ function relevanssi_uninstall_free() {
86
  delete_option( 'relevanssi_index_comments' );
87
  delete_option( 'relevanssi_index_excerpt' );
88
  delete_option( 'relevanssi_index_fields' );
 
89
  delete_option( 'relevanssi_index_post_types' );
90
  delete_option( 'relevanssi_index_taxonomies' );
91
  delete_option( 'relevanssi_index_taxonomies_list' );
@@ -103,6 +104,7 @@ function relevanssi_uninstall_free() {
103
  delete_option( 'relevanssi_show_matches' );
104
  delete_option( 'relevanssi_show_matches_text' );
105
  delete_option( 'relevanssi_show_post_controls' );
 
106
  delete_option( 'relevanssi_synonyms' );
107
  delete_option( 'relevanssi_thousand_separator' );
108
  delete_option( 'relevanssi_throttle' );
86
  delete_option( 'relevanssi_index_comments' );
87
  delete_option( 'relevanssi_index_excerpt' );
88
  delete_option( 'relevanssi_index_fields' );
89
+ delete_option( 'relevanssi_index_image_files' );
90
  delete_option( 'relevanssi_index_post_types' );
91
  delete_option( 'relevanssi_index_taxonomies' );
92
  delete_option( 'relevanssi_index_taxonomies_list' );
104
  delete_option( 'relevanssi_show_matches' );
105
  delete_option( 'relevanssi_show_matches_text' );
106
  delete_option( 'relevanssi_show_post_controls' );
107
+ delete_option( 'relevanssi_stopwords' );
108
  delete_option( 'relevanssi_synonyms' );
109
  delete_option( 'relevanssi_thousand_separator' );
110
  delete_option( 'relevanssi_throttle' );
readme.txt CHANGED
@@ -5,7 +5,7 @@ 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
 
@@ -133,6 +133,20 @@ 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.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.
@@ -187,6 +201,12 @@ Each document database is full of useless words. All the little words that appea
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
 
5
  Requires at least: 4.9
6
  Tested up to: 5.3
7
  Requires PHP: 5.6
8
+ Stable tag: 4.4.1
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.4.1 =
137
+ * Major fix: Returns the missing stopwords.
138
+
139
+ = 4.4.0 =
140
+ * New feature: It's now possible to exclude image attachments from the index with a simple setting on the indexing settings page.
141
+ * New feature: Page builder short codes are now removed in Relevanssi indexing. This should reduce the amount of garbage data indexed for posts in Divi, Avada and other page builder themes.
142
+ * Changed behaviour: The `relevanssi_page_builder_shortcodes` filter hook is now applied both in indexing and excerpts, and has a second parameter that will inform you of the current context.
143
+ * Minor fix: Stopwords weren't case insensitive like they should. They are now. Also, stopwords are no longer stored in the `wp_relevanssi_stopwords` database table, but are now stored in the `relevanssi_stopwords` option.
144
+ * Minor fix: A comma at the end of the custom field indexing setting made Relevanssi index all custom fields. This doesn't happen anymore and trailing commas are automatically removed, too.
145
+ * Minor fix: Accessibility improvements all around the admin interface. Screen reader support should be better, feel free to report any further ways to make this better.
146
+ * Minor fix: Doing searches without search terms and with the throttle disabled could cause problems. Relevanssi now makes sure throttle is always on when doing termless searches.
147
+ * Minor fix: Untokenized search terms are used for building excerpts, which makes highlighting in excerpts work better.
148
+ * Minor fix: Indexing did not adjust the number of posts indexed at one go like it should.
149
+
150
  = 4.3.4 =
151
  * 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.
152
  * New feature: Relevanssi automatically skips some custom fields from common plugins that only contain unnecessary metadata.
201
  * Deprecated: `relevanssi_get_term_taxonomy()` function is deprecated and will be removed at some point in the future.
202
 
203
  == Upgrade notice ==
204
+ = 4.4.1 =
205
+ * Fixes missing stopwords problem in 4.4.0.
206
+
207
+ = 4.4.0 =
208
+ * Changes in relevanssi_page_builder_shortcodes filter hook, page builder indexing and image attachments.
209
+
210
  = 4.3.4 =
211
  * Comment indexing bug fix, compatibility improvements and minor bug fixes and improvements.
212
 
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.4
17
  * Author: Mikko Saari
18
  * Author URI: http://www.mikkosaari.fi/
19
  * Text Domain: relevanssi
@@ -65,7 +65,7 @@ $relevanssi_variables['database_version'] = 5;
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';
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.4.1
17
  * Author: Mikko Saari
18
  * Author URI: http://www.mikkosaari.fi/
19
  * Text Domain: relevanssi
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.4.1';
69
 
70
  require_once 'lib/admin-ajax.php';
71
  require_once 'lib/common.php';
uninstall.php CHANGED
@@ -14,15 +14,15 @@ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
14
 
15
  global $wpdb;
16
  if ( ! defined( 'RELEVANSSI_PREMIUM' ) ) {
17
- define( 'RELEVANSSI_PREMIUM', false );
18
  }
19
  require_once 'lib/uninstall.php';
20
 
21
  if ( function_exists( 'is_multisite' ) && is_multisite() ) {
22
  $blogids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
23
  $old_blogid = $wpdb->blogid;
24
- foreach ( $blogids as $blog_id ) {
25
- switch_to_blog( $blog_id );
26
  relevanssi_uninstall_free();
27
  }
28
  switch_to_blog( $old_blogid );
14
 
15
  global $wpdb;
16
  if ( ! defined( 'RELEVANSSI_PREMIUM' ) ) {
17
+ define( 'RELEVANSSI_PREMIUM', false );
18
  }
19
  require_once 'lib/uninstall.php';
20
 
21
  if ( function_exists( 'is_multisite' ) && is_multisite() ) {
22
  $blogids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
23
  $old_blogid = $wpdb->blogid;
24
+ foreach ( $blogids as $uninstall_blog_id ) {
25
+ switch_to_blog( $uninstall_blog_id );
26
  relevanssi_uninstall_free();
27
  }
28
  switch_to_blog( $old_blogid );