Relevanssi – A Better Search - Version 4.0.9

Version Description

  • Fixes broken tag and category indexing and searching. If you use tags and categories, rebuild the index after updating.
  • Fixes phrase highlighting in documents.
  • New filter: relevanssi_indexing_restriction allows filtering posts before indexing.
  • New WooCommerce product visibility filtering tool makes WooCommerce product indexing faster.
  • MemberPress post controls were loose and showed drafts to searchers. That is now fixed.
  • Highlighting was too loose, even if matching was set to whole words.
  • Highlighting now works better in cases where there's a hyphen or an apostrophe inside a word.
Download this release

Release Info

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

Code changes from version 4.0.8 to 4.0.9

lib/common.php CHANGED
@@ -8,126 +8,6 @@
8
  * @see https://www.relevanssi.com/
9
  */
10
 
11
- /**
12
- * Filters posts based on WPML language.
13
- *
14
- * Attaches to 'relevanssi_hits_filter' to restrict WPML searches to the current
15
- * language. Whether this filter is used or not depends on the option
16
- * 'relevanssi_wpml_only_current'. Thanks to rvencu for the initial code.
17
- *
18
- * @global object $sitepress The WPML global object.
19
- *
20
- * @param array $data Index 0 has the array of results, index 1 has the search query.
21
- *
22
- * @return array $data The whole parameter array, with the filtered posts in the index 0.
23
- */
24
- function relevanssi_wpml_filter( $data ) {
25
- $filter_enabled = get_option( 'relevanssi_wpml_only_current' );
26
- if ( 'on' === $filter_enabled ) {
27
- $current_blog_language = get_bloginfo( 'language' );
28
- $filtered_hits = array();
29
- foreach ( $data[0] as $hit ) {
30
- if ( is_integer( $hit ) ) {
31
- // In case "fields" is set to "ids", fetch the post object we need.
32
- $hit = get_post( $hit );
33
- }
34
-
35
- if ( isset( $hit->blog_id ) ) {
36
- // This is a multisite search.
37
- switch_to_blog( $hit->blog_id );
38
- if ( function_exists( 'icl_object_id' ) ) {
39
- // Reset the WPML cache when blog is switched, otherwise WPML
40
- // will be confused.
41
- global $wpml_post_translations;
42
- $wpml_post_translations->reload();
43
- }
44
- }
45
-
46
- global $sitepress;
47
-
48
- // Check if WPML is used.
49
- if ( function_exists( 'icl_object_id' ) && ! function_exists( 'pll_is_translated_post_type' ) ) {
50
- if ( $sitepress->is_translated_post_type( $hit->post_type ) ) {
51
- $id = apply_filters( 'wpml_object_id', $hit->ID, $hit->post_type, false );
52
- // This is a post in a translated post type.
53
- if ( intval( $hit->ID ) === $id ) {
54
- // The post exists in the current language, and can be included.
55
- $filtered_hits[] = $hit;
56
- }
57
- } else {
58
- // This is not a translated post type, so include all posts.
59
- $filtered_hits[] = $hit;
60
- }
61
- } elseif ( get_bloginfo( 'language' ) === $current_blog_language ) {
62
- // If there is no WPML but the target blog has identical language with current blog,
63
- // we use the hits. Note en-US is not identical to en-GB!
64
- $filtered_hits[] = $hit;
65
- }
66
-
67
- if ( isset( $hit->blog_id ) ) {
68
- restore_current_blog();
69
- }
70
- }
71
-
72
- return array( $filtered_hits, $data[1] );
73
- }
74
-
75
- return $data;
76
- }
77
-
78
- /**
79
- * Removes the Polylang language filters.
80
- *
81
- * If the Polylang allow all option is enabled ('relevanssi_polylang_all_languages'),
82
- * removes the Polylang language filter. By default Polylang filters the languages
83
- * using a taxonomy query.
84
- *
85
- * @param object $query WP_Query object we need to clean up.
86
- */
87
- function relevanssi_polylang_filter( $query ) {
88
- $polylang_allow_all = get_option( 'relevanssi_polylang_all_languages' );
89
- if ( 'on' === $polylang_allow_all ) {
90
- $ok_queries = array();
91
-
92
- if ( ! isset( $query->tax_query ) ) {
93
- // No tax query set, backing off.
94
- return;
95
- }
96
-
97
- if ( ! isset( $query->tax_query->queries ) || ! is_array( $query->tax_query->queries ) ) {
98
- // No tax query set, backing off.
99
- return;
100
- }
101
-
102
- foreach ( $query->tax_query->queries as $tax_query ) {
103
- if ( 'language' !== $tax_query['taxonomy'] ) {
104
- // Not a language tax query.
105
- $ok_queries[] = $tax_query;
106
- }
107
- }
108
- $query->tax_query->queries = $ok_queries;
109
-
110
- if ( isset( $query->query_vars['tax_query'] ) ) {
111
- // Tax queries can be here as well, so let's sweep this one too.
112
- $ok_queries = array();
113
- foreach ( $query->query_vars['tax_query'] as $tax_query ) {
114
- if ( 'language' !== $tax_query['taxonomy'] ) {
115
- $ok_queries[] = $tax_query;
116
- }
117
- }
118
- $query->query_vars['tax_query'] = $ok_queries;
119
- }
120
-
121
- if ( isset( $query->query_vars['taxonomy'] ) && 'language' === $query->query_vars['taxonomy'] ) {
122
- // Another way to set the taxonomy.
123
- unset( $query->query_vars['taxonomy'] );
124
- unset( $query->query_vars['term'] );
125
- }
126
- }
127
-
128
- return $query;
129
- }
130
-
131
  /**
132
  * Gets the next key-direction pair from the orderby array.
133
  *
@@ -703,8 +583,10 @@ function relevanssi_default_post_ok( $post_ok, $post_id ) {
703
  }
704
  if ( class_exists( 'MeprUpdateCtrl' ) && MeprUpdateCtrl::is_activated() ) {
705
  // Memberpress.
706
- $post = get_post( $post_id );
707
- $post_ok = ! MeprRule::is_locked( $post );
 
 
708
  }
709
  if ( defined( 'SIMPLE_WP_MEMBERSHIP_VER' ) ) {
710
  // Simple Membership.
@@ -1740,9 +1622,10 @@ function relevanssi_add_highlight( $permalink ) {
1740
  if ( isset( $highlight_docs ) && 'off' !== $highlight_docs && ! empty( $query ) ) {
1741
  global $post;
1742
  $frontpage_id = get_option( 'page_on_front' );
 
1743
  if ( is_object( $post ) && $post->ID !== $frontpage_id ) {
1744
- // We won't add the highlight parameter for the front page, as that will break the link.
1745
- $permalink = esc_attr( add_query_arg( array( 'highlight' => rawurlencode( get_search_query() ) ), $permalink )
1746
  );
1747
  }
1748
  }
8
  * @see https://www.relevanssi.com/
9
  */
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  /**
12
  * Gets the next key-direction pair from the orderby array.
13
  *
583
  }
584
  if ( class_exists( 'MeprUpdateCtrl' ) && MeprUpdateCtrl::is_activated() ) {
585
  // Memberpress.
586
+ $post = get_post( $post_id );
587
+ if ( MeprRule::is_locked( $post ) ) {
588
+ $post_ok = false;
589
+ }
590
  }
591
  if ( defined( 'SIMPLE_WP_MEMBERSHIP_VER' ) ) {
592
  // Simple Membership.
1622
  if ( isset( $highlight_docs ) && 'off' !== $highlight_docs && ! empty( $query ) ) {
1623
  global $post;
1624
  $frontpage_id = get_option( 'page_on_front' );
1625
+ // We won't add the highlight parameter for the front page, as that will break the link.
1626
  if ( is_object( $post ) && $post->ID !== $frontpage_id ) {
1627
+ $query = str_replace( '"', '"', $query );
1628
+ $permalink = esc_attr( add_query_arg( array( 'highlight' => rawurlencode( $query ) ), $permalink )
1629
  );
1630
  }
1631
  }
lib/compatibility/polylang.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * /lib/compatibility/polylang.php
4
+ *
5
+ * Polylang compatibility features.
6
+ *
7
+ * @package Relevanssi
8
+ * @author Mikko Saari
9
+ * @license https://wordpress.org/about/gpl/ GNU General Public License
10
+ * @see https://www.relevanssi.com/
11
+ */
12
+
13
+ add_filter( 'relevanssi_modify_wp_query', 'relevanssi_polylang_filter' );
14
+
15
+ /**
16
+ * Removes the Polylang language filters.
17
+ *
18
+ * If the Polylang allow all option is enabled ('relevanssi_polylang_all_languages'),
19
+ * removes the Polylang language filter. By default Polylang filters the languages
20
+ * using a taxonomy query.
21
+ *
22
+ * @param object $query WP_Query object we need to clean up.
23
+ */
24
+ function relevanssi_polylang_filter( $query ) {
25
+ $polylang_allow_all = get_option( 'relevanssi_polylang_all_languages' );
26
+ if ( 'on' === $polylang_allow_all ) {
27
+ $ok_queries = array();
28
+
29
+ if ( ! isset( $query->tax_query ) ) {
30
+ // No tax query set, backing off.
31
+ return;
32
+ }
33
+
34
+ if ( ! isset( $query->tax_query->queries ) || ! is_array( $query->tax_query->queries ) ) {
35
+ // No tax query set, backing off.
36
+ return;
37
+ }
38
+
39
+ foreach ( $query->tax_query->queries as $tax_query ) {
40
+ if ( 'language' !== $tax_query['taxonomy'] ) {
41
+ // Not a language tax query.
42
+ $ok_queries[] = $tax_query;
43
+ }
44
+ }
45
+ $query->tax_query->queries = $ok_queries;
46
+
47
+ if ( isset( $query->query_vars['tax_query'] ) ) {
48
+ // Tax queries can be here as well, so let's sweep this one too.
49
+ $ok_queries = array();
50
+ foreach ( $query->query_vars['tax_query'] as $tax_query ) {
51
+ if ( 'language' !== $tax_query['taxonomy'] ) {
52
+ $ok_queries[] = $tax_query;
53
+ }
54
+ }
55
+ $query->query_vars['tax_query'] = $ok_queries;
56
+ }
57
+
58
+ if ( isset( $query->query_vars['taxonomy'] ) && 'language' === $query->query_vars['taxonomy'] ) {
59
+ // Another way to set the taxonomy.
60
+ unset( $query->query_vars['taxonomy'] );
61
+ unset( $query->query_vars['term'] );
62
+ }
63
+ }
64
+
65
+ return $query;
66
+ }
lib/compatibility/woocommerce.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * /lib/compatibility/woocommerce.php
4
+ *
5
+ * WooCommerce compatibility features.
6
+ *
7
+ * @package Relevanssi
8
+ * @author Mikko Saari
9
+ * @license https://wordpress.org/about/gpl/ GNU General Public License
10
+ * @see https://www.relevanssi.com/
11
+ */
12
+
13
+ add_filter( 'relevanssi_indexing_restriction', 'relevanssi_woocommerce_restriction' );
14
+
15
+ /**
16
+ * Applies the WooCommerce product visibility filter.
17
+ *
18
+ * @param string $restriction The restriction clause.
19
+ *
20
+ * @return string The restriction clause with the WC filter added, if necessary.
21
+ */
22
+ function relevanssi_woocommerce_restriction( $restriction ) {
23
+ $restriction .= relevanssi_woocommerce_indexing_filter();
24
+ return $restriction;
25
+ }
26
+
27
+ /**
28
+ * WooCommerce product visibility filtering for indexing.
29
+ *
30
+ * This filter is applied before the posts are selected for indexing, so this will
31
+ * skip all the excluded posts right away.
32
+ *
33
+ * @since 4.0.9 (2.1.5)
34
+ * @global $wpdb The WordPress database interface.
35
+ *
36
+ * @return string $restriction The query restriction for the WooCommerce filtering.
37
+ */
38
+ function relevanssi_woocommerce_indexing_filter() {
39
+ global $wpdb;
40
+
41
+ $restriction = '';
42
+ $woocommerce_blocks = array(
43
+ 'outofstock' => false,
44
+ 'exclude-from-catalog' => false,
45
+ 'exclude-from-search' => false,
46
+ );
47
+ /**
48
+ * Controls the WooCommerce product visibility filtering.
49
+ *
50
+ * @param array $woocommerce_blocks Has three keys: 'outofstock',
51
+ * 'exclude-from-catalog' and 'exclude-from-search', matching three different
52
+ * product visibility settings. If the filter sets some of these to 'true',
53
+ * those posts will be filtered in the indexing.
54
+ */
55
+ $woocommerce_blocks = apply_filters( 'relevanssi_woocommerce_indexing', $woocommerce_blocks );
56
+ $term_taxonomy_id_array = array();
57
+ if ( $woocommerce_blocks['outofstock'] ) {
58
+ $out_of_stock = get_term_by( 'slug', 'outofstock', 'product_visibility', OBJECT );
59
+ if ( $out_of_stock && isset( $out_of_stock->term_taxonomy_id ) ) {
60
+ $term_taxonomy_id_array[] = $out_of_stock->term_taxonomy_id;
61
+ }
62
+ }
63
+ if ( $woocommerce_blocks['exclude-from-catalog'] ) {
64
+ $exclude_from_catalog = get_term_by( 'slug', 'exclude-from-catalog', 'product_visibility', OBJECT );
65
+ if ( $exclude_from_catalog && isset( $exclude_from_catalog->term_taxonomy_id ) ) {
66
+ $term_taxonomy_id_array[] = $exclude_from_catalog->term_taxonomy_id;
67
+ }
68
+ }
69
+ if ( $woocommerce_blocks['exclude-from-search'] ) {
70
+ $exclude_from_search = get_term_by( 'slug', 'exclude-from-search', 'product_visibility', OBJECT );
71
+ if ( $exclude_from_search && isset( $exclude_from_search->term_taxonomy_id ) ) {
72
+ $term_taxonomy_id_array[] = $exclude_from_search->term_taxonomy_id;
73
+ }
74
+ }
75
+ if ( ! empty( $term_taxonomy_id_array ) ) {
76
+ $term_taxonomy_id_string = implode( ',', $term_taxonomy_id_array );
77
+ $restriction .= " AND post.ID NOT IN (SELECT object_id FROM $wpdb->term_relationships WHERE object_id = post.ID AND term_taxonomy_id IN ($term_taxonomy_id_string)) ";
78
+ }
79
+ return $restriction;
80
+ }
lib/compatibility/wpml.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * /lib/compatibility/wpml.php
4
+ *
5
+ * WPML filtering function.
6
+ *
7
+ * @package Relevanssi
8
+ * @author Mikko Saari
9
+ * @license https://wordpress.org/about/gpl/ GNU General Public License
10
+ * @see https://www.relevanssi.com/
11
+ */
12
+
13
+ add_filter( 'relevanssi_hits_filter', 'relevanssi_wpml_filter' );
14
+
15
+ /**
16
+ * Filters posts based on WPML language.
17
+ *
18
+ * Attaches to 'relevanssi_hits_filter' to restrict WPML searches to the current
19
+ * language. Whether this filter is used or not depends on the option
20
+ * 'relevanssi_wpml_only_current'. Thanks to rvencu for the initial code.
21
+ *
22
+ * @global object $sitepress The WPML global object.
23
+ *
24
+ * @param array $data Index 0 has the array of results, index 1 has the search query.
25
+ *
26
+ * @return array $data The whole parameter array, with the filtered posts in the index 0.
27
+ */
28
+ function relevanssi_wpml_filter( $data ) {
29
+ $filter_enabled = get_option( 'relevanssi_wpml_only_current' );
30
+ if ( 'on' === $filter_enabled ) {
31
+ $current_blog_language = get_bloginfo( 'language' );
32
+ $filtered_hits = array();
33
+ foreach ( $data[0] as $hit ) {
34
+ if ( is_integer( $hit ) ) {
35
+ // In case "fields" is set to "ids", fetch the post object we need.
36
+ $hit = get_post( $hit );
37
+ }
38
+
39
+ if ( isset( $hit->blog_id ) ) {
40
+ // This is a multisite search.
41
+ switch_to_blog( $hit->blog_id );
42
+ if ( function_exists( 'icl_object_id' ) ) {
43
+ // Reset the WPML cache when blog is switched, otherwise WPML
44
+ // will be confused.
45
+ global $wpml_post_translations;
46
+ $wpml_post_translations->reload();
47
+ }
48
+ }
49
+
50
+ global $sitepress;
51
+
52
+ // Check if WPML is used.
53
+ if ( function_exists( 'icl_object_id' ) && ! function_exists( 'pll_is_translated_post_type' ) ) {
54
+ if ( $sitepress->is_translated_post_type( $hit->post_type ) ) {
55
+ $id = apply_filters( 'wpml_object_id', $hit->ID, $hit->post_type, false );
56
+ // This is a post in a translated post type.
57
+ if ( intval( $hit->ID ) === $id ) {
58
+ // The post exists in the current language, and can be included.
59
+ $filtered_hits[] = $hit;
60
+ }
61
+ } else {
62
+ // This is not a translated post type, so include all posts.
63
+ $filtered_hits[] = $hit;
64
+ }
65
+ } elseif ( get_bloginfo( 'language' ) === $current_blog_language ) {
66
+ // If there is no WPML but the target blog has identical language with current blog,
67
+ // we use the hits. Note en-US is not identical to en-GB!
68
+ $filtered_hits[] = $hit;
69
+ }
70
+
71
+ if ( isset( $hit->blog_id ) ) {
72
+ restore_current_blog();
73
+ }
74
+ }
75
+
76
+ return array( $filtered_hits, $data[1] );
77
+ }
78
+
79
+ return $data;
80
+ }
lib/excerpts-highlights.php CHANGED
@@ -62,7 +62,7 @@ function relevanssi_do_excerpt( $t_post, $query ) {
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' );
66
  /**
67
  * Filters the excerpt-building problem shortcodes.
68
  *
@@ -500,10 +500,9 @@ function relevanssi_highlight_terms( $content, $query, $in_docs = false ) {
500
 
501
  if ( $word_boundaries ) {
502
  $regex = "/(\b$pr_term\b)/iu";
503
- if ( 'none' !== get_option( 'relevanssi_fuzzy' ) ) {
504
  $regex = "/(\b$pr_term|$pr_term\b)/iu";
505
  }
506
-
507
  $content = preg_replace( $regex, $start_emp_token . '\\1' . $end_emp_token, $content );
508
  if ( empty( $content ) ) {
509
  $content = preg_replace( $regex, $start_emp_token . '\\1' . $end_emp_token, $undecoded_content );
@@ -945,8 +944,19 @@ function relevanssi_add_accent_variations( $word ) {
945
  'to' => array( '(a|á|à|â)', '(c|ç)', '(e|é|è|ê|ë)', '(i|í|ì|î|ï)', '(o|ó|ò|ô|õ)', '(u|ú|ù|ü|û)', '(n|ñ)', '(ss|ß)' ),
946
  ));
947
 
 
 
 
 
 
 
 
 
948
  $word = str_ireplace( $replacement_arrays['from'], $replacement_arrays['to'], $word );
949
 
 
 
 
950
  return $word;
951
  }
952
 
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
  /**
67
  * Filters the excerpt-building problem shortcodes.
68
  *
500
 
501
  if ( $word_boundaries ) {
502
  $regex = "/(\b$pr_term\b)/iu";
503
+ if ( 'never' !== get_option( 'relevanssi_fuzzy' ) ) {
504
  $regex = "/(\b$pr_term|$pr_term\b)/iu";
505
  }
 
506
  $content = preg_replace( $regex, $start_emp_token . '\\1' . $end_emp_token, $content );
507
  if ( empty( $content ) ) {
508
  $content = preg_replace( $regex, $start_emp_token . '\\1' . $end_emp_token, $undecoded_content );
944
  'to' => array( '(a|á|à|â)', '(c|ç)', '(e|é|è|ê|ë)', '(i|í|ì|î|ï)', '(o|ó|ò|ô|õ)', '(u|ú|ù|ü|û)', '(n|ñ)', '(ss|ß)' ),
945
  ));
946
 
947
+ $len = mb_strlen( $word );
948
+ $word_array = array();
949
+ for ( $i = 0; $i < $len; $i++ ) {
950
+ $char = mb_substr( $word, $i, 1 );
951
+ $word_array[] = $char;
952
+ }
953
+ $word = implode( '-?', $word_array );
954
+
955
  $word = str_ireplace( $replacement_arrays['from'], $replacement_arrays['to'], $word );
956
 
957
+ $word = preg_replace( '/s$/', "(s|'s|’s)", $word );
958
+ $word = preg_replace( '/^o/', "(o|o'|o’)", $word );
959
+
960
  return $word;
961
  }
962
 
lib/indexing.php CHANGED
@@ -100,6 +100,8 @@ function relevanssi_generate_indexing_query( $valid_status, $extend = false, $re
100
  global $wpdb, $relevanssi_variables;
101
  $relevanssi_table = $relevanssi_variables['relevanssi_table'];
102
 
 
 
103
  if ( ! $extend ) {
104
  $q = "SELECT post.ID
105
  FROM $wpdb->posts post
@@ -1024,7 +1026,7 @@ function relevanssi_index_taxonomy_terms( $post = null, $taxonomy = '', $insert_
1024
  foreach ( $tag_tokens as $token => $count ) {
1025
  $n++;
1026
 
1027
- if ( 'post_tags' === $taxonomy ) {
1028
  $insert_data[ $token ]['tag'] = $count;
1029
  } elseif ( 'category' === $taxonomy ) {
1030
  $insert_data[ $token ]['category'] = $count;
100
  global $wpdb, $relevanssi_variables;
101
  $relevanssi_table = $relevanssi_variables['relevanssi_table'];
102
 
103
+ $restriction = apply_filters( 'relevanssi_indexing_restriction', $restriction );
104
+
105
  if ( ! $extend ) {
106
  $q = "SELECT post.ID
107
  FROM $wpdb->posts post
1026
  foreach ( $tag_tokens as $token => $count ) {
1027
  $n++;
1028
 
1029
+ if ( 'post_tag' === $taxonomy ) {
1030
  $insert_data[ $token ]['tag'] = $count;
1031
  } elseif ( 'category' === $taxonomy ) {
1032
  $insert_data[ $token ]['category'] = $count;
lib/init.php CHANGED
@@ -20,10 +20,6 @@ add_action( 'admin_enqueue_scripts', 'relevanssi_add_admin_scripts' );
20
  add_filter( 'the_posts', 'relevanssi_query', 99, 2 );
21
  add_filter( 'posts_request', 'relevanssi_prevent_default_request', 10, 2 );
22
 
23
- // Multilingual plugin support.
24
- add_filter( 'relevanssi_hits_filter', 'relevanssi_wpml_filter' );
25
- add_filter( 'relevanssi_modify_wp_query', 'relevanssi_polylang_filter' );
26
-
27
  // Post indexing.
28
  add_action( 'wp_insert_post', 'relevanssi_insert_edit', 99, 1 );
29
  add_action( 'delete_post', 'relevanssi_remove_doc' );
@@ -121,6 +117,18 @@ function relevanssi_init() {
121
  wp_clear_scheduled_hook( 'relevanssi_trim_logs' );
122
  }
123
  }
 
 
 
 
 
 
 
 
 
 
 
 
124
  }
125
 
126
  /**
20
  add_filter( 'the_posts', 'relevanssi_query', 99, 2 );
21
  add_filter( 'posts_request', 'relevanssi_prevent_default_request', 10, 2 );
22
 
 
 
 
 
23
  // Post indexing.
24
  add_action( 'wp_insert_post', 'relevanssi_insert_edit', 99, 1 );
25
  add_action( 'delete_post', 'relevanssi_remove_doc' );
117
  wp_clear_scheduled_hook( 'relevanssi_trim_logs' );
118
  }
119
  }
120
+
121
+ if ( function_exists( 'icl_object_id' ) && ! function_exists( 'pll_is_translated_post_type' ) ) {
122
+ require_once 'compatibility/wpml.php';
123
+ }
124
+
125
+ if ( function_exists( 'pll_get_post' ) ) {
126
+ require_once 'compatibility/polylang.php';
127
+ }
128
+
129
+ if ( class_exists( 'WooCommerce' ) ) {
130
+ require_once 'compatibility/woocommerce.php';
131
+ }
132
  }
133
 
134
  /**
lib/interface.php CHANGED
@@ -479,62 +479,6 @@ function relevanssi_truncate_logs( $verbose = true ) {
479
  return $result;
480
  }
481
 
482
- /**
483
- * Displays the list of most common words in the index.
484
- *
485
- * @global object $wpdb The WP database interface.
486
- * @global array $relevanssi_variables The global Relevanssi variables.
487
- *
488
- * @param int $limit How many words to display, default 25.
489
- * @param boolean $wp_cli If true, return just a list of words. If false, print out
490
- * HTML code.
491
- *
492
- * @return array A list of words, if $wp_cli is true.
493
- */
494
- function relevanssi_common_words( $limit = 25, $wp_cli = false ) {
495
- global $wpdb, $relevanssi_variables;
496
-
497
- $plugin = 'relevanssi';
498
- if ( RELEVANSSI_PREMIUM ) {
499
- $plugin = 'relevanssi-premium';
500
- }
501
-
502
- if ( ! is_numeric( $limit ) ) {
503
- $limit = 25;
504
- }
505
-
506
- $words = $wpdb->get_results( 'SELECT COUNT(*) as cnt, term FROM ' . $relevanssi_variables['relevanssi_table'] . " GROUP BY term ORDER BY cnt DESC LIMIT $limit" ); // WPCS: unprepared sql ok, Relevanssi table name and $limit is numeric.
507
-
508
- if ( ! $wp_cli ) {
509
- printf( '<h2>%s</h2>', esc_html__( '25 most common words in the index', 'relevanssi' ) );
510
- printf( '<p>%s</p>', esc_html__( "These words are excellent stopword material. A word that appears in most of the posts in the database is quite pointless when searching. This is also an easy way to create a completely new stopword list, if one isn't available in your language. Click the icon after the word to add the word to the stopword list. The word will also be removed from the index, so rebuilding the index is not necessary.", 'relevanssi' ) );
511
-
512
- ?>
513
- <input type="hidden" name="dowhat" value="add_stopword" />
514
- <table class="form-table">
515
- <tr>
516
- <th scope="row"><?php esc_html_e( 'Stopword Candidates', 'relevanssi' ); ?></th>
517
- <td>
518
- <ul>
519
- <?php
520
- $src = plugins_url( 'delete.png', $relevanssi_variables['file'] );
521
-
522
- foreach ( $words as $word ) {
523
- $stop = __( 'Add to stopwords', 'relevanssi' );
524
- printf( '<li>%1$s (%2$d) <input style="padding: 0; margin: 0" type="image" src="%3$s" alt="%4$s" name="term" value="%5$s"/></li>', esc_html( $word->term ), esc_html( $word->cnt ), esc_attr( $src ), esc_attr( $stop ), esc_attr( $word->term ) );
525
- }
526
- ?>
527
- </ul>
528
- </td>
529
- </tr>
530
- </table>
531
- <?php
532
-
533
- }
534
-
535
- return $words;
536
- }
537
-
538
  /**
539
  * Shows the query log with the most common queries
540
  *
@@ -752,91 +696,6 @@ function relevanssi_options_form() {
752
  wp_enqueue_script( 'dashboard' );
753
  wp_print_scripts( 'dashboard' );
754
 
755
- $excerpts = get_option( 'relevanssi_excerpts' );
756
- $excerpt_length = get_option( 'relevanssi_excerpt_length' );
757
- $excerpt_type = get_option( 'relevanssi_excerpt_type' );
758
- $excerpt_allowable_tags = get_option( 'relevanssi_excerpt_allowable_tags' );
759
- $excerpt_custom_fields = get_option( 'relevanssi_excerpt_custom_fields' );
760
- $highlight = get_option( 'relevanssi_highlight' );
761
- $txt_col = get_option( 'relevanssi_txt_col' );
762
- $bg_col = get_option( 'relevanssi_bg_col' );
763
- $css = get_option( 'relevanssi_css' );
764
- $class = get_option( 'relevanssi_class' );
765
- $synonyms = get_option( 'relevanssi_synonyms' );
766
- $highlight_title = get_option( 'relevanssi_hilite_title' );
767
- $index_comments = get_option( 'relevanssi_index_comments' );
768
- $highlight_docs = get_option( 'relevanssi_highlight_docs' );
769
- $highlight_coms = get_option( 'relevanssi_highlight_comments' );
770
- $show_matches = get_option( 'relevanssi_show_matches' );
771
- $show_matches_text = get_option( 'relevanssi_show_matches_text' );
772
- $word_boundaries = get_option( 'relevanssi_word_boundaries' );
773
- $punctuation = get_option( 'relevanssi_punctuation' );
774
-
775
- if ( '#' !== substr( $txt_col, 0, 1 ) ) {
776
- $txt_col = '#' . $txt_col;
777
- }
778
- $txt_col = relevanssi_sanitize_hex_color( $txt_col );
779
- if ( '#' !== substr( $bg_col, 0, 1 ) ) {
780
- $bg_col = '#' . $bg_col;
781
- }
782
- $bg_col = relevanssi_sanitize_hex_color( $bg_col );
783
-
784
- $excerpts = relevanssi_check( $excerpts );
785
- $excerpt_custom_fields = relevanssi_check( $excerpt_custom_fields );
786
- $highlight_title = relevanssi_check( $highlight_title );
787
- $highlight_docs = relevanssi_check( $highlight_docs );
788
- $highlight_coms = relevanssi_check( $highlight_coms );
789
- $show_matches = relevanssi_check( $show_matches );
790
- $word_boundaries = relevanssi_check( $word_boundaries );
791
- $excerpt_chars = relevanssi_select( $excerpt_type, 'chars' );
792
- $excerpt_words = relevanssi_select( $excerpt_type, 'words' );
793
- $highlight_none = relevanssi_select( $highlight, 'no' );
794
- $highlight_mark = relevanssi_select( $highlight, 'mark' );
795
- $highlight_em = relevanssi_select( $highlight, 'em' );
796
- $highlight_strong = relevanssi_select( $highlight, 'strong' );
797
- $highlight_col = relevanssi_select( $highlight, 'col' );
798
- $highlight_bgcol = relevanssi_select( $highlight, 'bgcol' );
799
- $highlight_style = relevanssi_select( $highlight, 'style' );
800
- $highlight_class = relevanssi_select( $highlight, 'class' );
801
-
802
- $show_matches_text = stripslashes( $show_matches_text );
803
-
804
- $txt_col_display = 'screen-reader-text';
805
- $bg_col_display = 'screen-reader-text';
806
- $css_display = 'screen-reader-text';
807
- $class_display = 'screen-reader-text';
808
-
809
- if ( 'col' === $highlight ) {
810
- $txt_col_display = '';
811
- }
812
- if ( 'bgcol' === $highlight ) {
813
- $bg_col_display = '';
814
- }
815
- if ( 'style' === $highlight ) {
816
- $css_display = '';
817
- }
818
- if ( 'class' === $highlight ) {
819
- $class_display = '';
820
- }
821
-
822
- if ( isset( $synonyms ) ) {
823
- $synonyms = str_replace( ';', "\n", $synonyms );
824
- } else {
825
- $synonyms = '';
826
- }
827
-
828
- if ( RELEVANSSI_PREMIUM ) {
829
- $api_key = get_option( 'relevanssi_api_key' );
830
- $disable_shortcodes = get_option( 'relevanssi_disable_shortcodes' );
831
- $hide_post_controls = get_option( 'relevanssi_hide_post_controls' );
832
- $server_location = get_option( 'relevanssi_server_location' );
833
- $show_post_controls = get_option( 'relevanssi_show_post_controls' );
834
- $thousand_separator = get_option( 'relevanssi_thousand_separator' );
835
-
836
- $hide_post_controls = relevanssi_check( $hide_post_controls );
837
- $show_post_controls = relevanssi_check( $show_post_controls );
838
- }
839
-
840
  echo "<div class='postbox-container'>";
841
  echo "<form method='post'>";
842
 
@@ -872,102 +731,14 @@ function relevanssi_options_form() {
872
  <?php endif; ?>
873
  </h2>
874
 
875
- <?php
876
- if ( 'overview' === $active_tab ) :
877
- if ( ! RELEVANSSI_PREMIUM ) {
878
- $display_save_button = false;
879
- }
880
- ?>
881
-
882
- <h2><?php esc_html_e( 'Welcome to Relevanssi!', 'relevanssi' ); ?></h2>
883
-
884
- <table class="form-table">
885
- <?php
886
- if ( ! is_multisite() && function_exists( 'relevanssi_form_api_key' ) ) {
887
- relevanssi_form_api_key( $api_key );
888
- }
889
- if ( function_exists( 'relevanssi_form_hide_post_controls' ) ) {
890
- relevanssi_form_hide_post_controls( $hide_post_controls, $show_post_controls );
891
- }
892
- ?>
893
- <tr>
894
- <th scope="row"><?php esc_html_e( 'Getting started', 'relevanssi' ); ?></th>
895
- <td>
896
- <p><?php esc_html_e( "You've already installed Relevanssi. That's a great first step towards good search experience!", 'relevanssi' ); ?></p>
897
- <ol>
898
- <?php if ( 'done' !== get_option( 'relevanssi_indexed' ) ) : ?>
899
- <?php // Translators: %1$s opens the link, %2$s is the anchor text, %3$s closes the link. ?>
900
- <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>
901
- <p><?php esc_html_e( 'You need to check at least the following options:', 'relevanssi' ); ?><br />
902
- – <?php esc_html_e( 'Make sure the post types you want to include in the index are indexed.', 'relevanssi' ); ?><br />
903
- <?php // Translators: %s is '_sku'. ?>
904
- – <?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>
905
- <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>
906
- </li>
907
- <?php else : ?>
908
- <li><p><?php esc_html_e( 'Great, you already have an index!', 'relevanssi' ); ?></p></li>
909
- <?php endif; ?>
910
- <li>
911
- <?php // Translators: %1$s opens the link, %2$s is the anchor text, %3$s closes the link. ?>
912
- <p><?php printf( esc_html__( 'On the %1$s%2$s%3$s tab, choose whether you want the default operator to be AND (less results, but more precise) or OR (more results, less precise).', 'relevanssi' ), "<a href='" . esc_attr( $this_page ) . "&amp;tab=searching'>", esc_html__( 'Searching', 'relevanssi' ), '</a>' ); ?></p>
913
- </li>
914
- <li>
915
- <?php // Translators: %1$s opens the link, %2$s is the anchor text, %3$s closes the link. ?>
916
- <p><?php printf( esc_html__( 'The next step is the %1$s%2$s%3$s tab, where you can enable the custom excerpts that show the relevant part of post in the search results pages.', 'relevanssi' ), "<a href='" . esc_attr( $this_page ) . "&amp;tab=excerpts'>", esc_html__( 'Excerpts and highlights', 'relevanssi' ), '</a>' ); ?></p>
917
- <p><?php esc_html_e( 'There are couple of options related to that, so if you want highlighting in the results, you can adjust the styles for that to suit the look of your site.', 'relevanssi' ); ?></p>
918
- </li>
919
- <li>
920
- <p><?php esc_html_e( "That's about it! Now you should have Relevanssi up and running. The rest of the options is mostly fine-tuning.", 'relevanssi' ); ?></p>
921
- </li>
922
- </ol>
923
- <p><?php esc_html_e( "Relevanssi doesn't have a separate search widget. Instead, Relevanssi uses the default search widget. Any standard search form will do!", 'relevanssi' ); ?></p>
924
- </td>
925
- </tr>
926
- <tr>
927
- <th scope="row"><?php esc_html_e( 'For more information', 'relevanssi' ); ?></th>
928
- <td>
929
- <p><?php esc_html_e( "Relevanssi uses the WordPress contextual help. Click 'Help' on the top right corner for more information on many Relevanssi topics.", 'relevanssi' ); ?></p>
930
- <?php // Translators: %1$s opens the link, %2$s closes the link. ?>
931
- <p><?php printf( esc_html__( '%1$sRelevanssi knowledge base%2$s has lots of information about advanced Relevanssi use, including plenty of code samples.', 'relevanssi' ), "<a href='https://www.relevanssi.com/knowledge-base/'>", '</a>' ); ?></p>
932
- </td>
933
- </tr>
934
- <tr>
935
- <th scope="row">
936
- <?php esc_html_e( 'Relevanssi on Facebook', 'relevanssi' ); ?>
937
- </th>
938
- <td>
939
- <p><a href="https://www.facebook.com/relevanssi"><?php esc_html_e( 'Check out the Relevanssi page on Facebook for news and updates about Relevanssi.', 'relevanssi' ); ?></a></p>
940
- </td>
941
- </tr>
942
- <?php if ( ! RELEVANSSI_PREMIUM ) { ?>
943
- <tr>
944
- <th scope="row">
945
- <?php esc_html_e( 'Buy Relevanssi Premium', 'relevanssi' ); ?>
946
- </th>
947
- <td>
948
- <p><a href="https://www.relevanssi.com/buy-premium"><?php esc_html_e( 'Buy Relevanssi Premium now', 'relevanssi' ); ?></a> –
949
- <?php // Translators: %1$s is the coupon code, %2$s is the year it expires. ?>
950
- <?php printf( esc_html__( 'use coupon code %1$s for 20%% discount (valid at least until the end of %2$s)', 'relevanssi' ), '<strong>FREE2018</strong>', '2018' ); ?></p>
951
- <p><?php esc_html_e( 'Here are some improvements Relevanssi Premium offers:', 'relevanssi' ); ?></p>
952
- <ul class="relevanssi_ul">
953
- <li><?php esc_html_e( 'PDF content indexing', 'relevanssi' ); ?></li>
954
- <li><?php esc_html_e( 'Index and search user profile pages', 'relevanssi' ); ?></li>
955
- <li><?php esc_html_e( 'Index and search taxonomy term pages', 'relevanssi' ); ?></li>
956
- <li><?php esc_html_e( 'Multisite searches across many subsites', 'relevanssi' ); ?></li>
957
- <li><?php esc_html_e( 'WP CLI commands', 'relevanssi' ); ?></li>
958
- <li><?php esc_html_e( 'Adjust weights separately for each post type and taxonomy', 'relevanssi' ); ?></li>
959
- <li><?php esc_html_e( 'Internal link anchors can be search terms for the target posts', 'relevanssi' ); ?></li>
960
- <li><?php esc_html_e( 'Index and search any columns in the wp_posts database', 'relevanssi' ); ?></li>
961
- <li><?php esc_html_e( 'Hide Relevanssi branding from the User Searches page on a client installation', 'relevanssi' ); ?></li>
962
- </ul>
963
- </td>
964
- </tr>
965
- <?php } // End if ( ! RELEVANSSI_PREMIUM ). ?>
966
- </table>
967
-
968
- <?php endif; // Active tab: basic. ?>
969
-
970
  <?php
 
 
 
 
 
 
 
971
  if ( 'logging' === $active_tab ) {
972
  require_once 'tabs/logging-tab.php';
973
  relevanssi_logging_tab();
@@ -976,456 +747,42 @@ if ( function_exists( 'relevanssi_form_hide_post_controls' ) ) {
976
  require_once 'tabs/searching-tab.php';
977
  relevanssi_searching_tab();
978
  }
979
- ?>
980
-
981
- <?php
982
- if ( 'excerpts' === $active_tab ) :
983
- $index_fields = get_option( 'relevanssi_index_fields' );
984
- ?>
985
-
986
- <h2 id="excerpts"><?php esc_html_e( 'Custom excerpts/snippets', 'relevanssi' ); ?></h2>
987
-
988
- <table class="form-table">
989
- <tr>
990
- <th scope="row">
991
- <label for='relevanssi_excerpts'><?php esc_html_e( 'Custom search result snippets', 'relevanssi' ); ?></label>
992
- </th>
993
- <td>
994
- <fieldset>
995
- <legend class="screen-reader-text"><?php esc_html_e( 'Create custom search result snippets', 'relevanssi' ); ?></legend>
996
- <label >
997
- <input type='checkbox' name='relevanssi_excerpts' id='relevanssi_excerpts' <?php echo esc_html( $excerpts ); ?> />
998
- <?php esc_html_e( 'Create custom search result snippets', 'relevanssi' ); ?>
999
- </label>
1000
- </fieldset>
1001
- <p class="description"><?php esc_html_e( 'Only enable this if you actually use the custom excerpts.', 'relevanssi' ); ?></p>
1002
- </td>
1003
- </tr>
1004
- <tr id="tr_excerpt_length"
1005
- <?php
1006
- if ( empty( $excerpts ) ) {
1007
- echo "class='relevanssi_disabled'";
1008
  }
1009
- ?>
1010
- >
1011
- <th scope="row">
1012
- <label for='relevanssi_excerpt_length'><?php esc_html_e( 'Length of the snippet', 'relevanssi' ); ?></label>
1013
- </th>
1014
- <td>
1015
- <input type='text' name='relevanssi_excerpt_length' id='relevanssi_excerpt_length' size='4' value='<?php echo esc_attr( $excerpt_length ); ?>'
1016
- <?php
1017
- if ( empty( $excerpts ) ) {
1018
- echo "disabled='disabled'";
1019
- }
1020
- ?>
1021
- />
1022
- <select name='relevanssi_excerpt_type' id='relevanssi_excerpt_type'
1023
- <?php
1024
- if ( empty( $excerpts ) ) {
1025
- echo "disabled='disabled'";
1026
- }
1027
- ?>
1028
- >
1029
- <option value='chars' <?php echo esc_html( $excerpt_chars ); ?>><?php esc_html_e( 'characters', 'relevanssi' ); ?></option>
1030
- <option value='words' <?php echo esc_html( $excerpt_words ); ?>><?php esc_html_e( 'words', 'relevanssi' ); ?></option>
1031
- </select>
1032
- <p class="description"><?php esc_html_e( "Using words is much faster than characters. Don't use characters, unless you have a really good reason and your posts are short.", 'relevanssi' ); ?></p>
1033
- </td>
1034
- </tr>
1035
- <tr id="tr_excerpt_allowable_tags"
1036
- <?php
1037
- if ( empty( $excerpts ) ) {
1038
- echo "class='relevanssi_disabled'";
1039
- }
1040
- ?>
1041
- >
1042
- <th scope="row">
1043
- <label for='relevanssi_excerpt_allowable_tags'><?php esc_html_e( 'Allowable tags in excerpts', 'relevanssi' ); ?></label>
1044
- </th>
1045
- <td>
1046
- <input type='text' name='relevanssi_excerpt_allowable_tags' id='relevanssi_excerpt_allowable_tags' size='60' value='<?php echo esc_attr( $excerpt_allowable_tags ); ?>'
1047
- <?php
1048
- if ( empty( $excerpts ) ) {
1049
- echo "disabled='disabled'";
1050
- }
1051
- ?>
1052
- />
1053
- <p class="description"><?php esc_html_e( 'List all tags you want to allow in excerpts. For example: &lt;p&gt;&lt;a&gt;&lt;strong&gt;.', 'relevanssi' ); ?></p>
1054
- </td>
1055
- </tr>
1056
- <tr id="tr_excerpt_custom_fields"
1057
- <?php
1058
- if ( empty( $excerpts ) ) {
1059
- echo "class='relevanssi_disabled'";
1060
- }
1061
- ?>
1062
- >
1063
- <th scope="row">
1064
- <label for='relevanssi_excerpt_custom_fields'><?php esc_html_e( 'Use custom fields for excerpts', 'relevanssi' ); ?></label>
1065
- </th>
1066
- <td>
1067
- <fieldset>
1068
- <legend class="screen-reader-text"><?php esc_html_e( 'Use custom field content for building excerpts', 'relevanssi' ); ?></legend>
1069
- <label>
1070
- <input type='checkbox' name='relevanssi_excerpt_custom_fields' id='relevanssi_excerpt_custom_fields' <?php echo esc_html( $excerpt_custom_fields ); ?>
1071
- <?php
1072
- if ( empty( $excerpts ) || empty( $index_fields ) ) {
1073
- echo "disabled='disabled'";
1074
- }
1075
- ?>
1076
- />
1077
- <?php esc_html_e( 'Use custom field content for building excerpts', 'relevanssi' ); ?>
1078
- </label>
1079
- </fieldset>
1080
- <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' ); ?>
1081
- <?php
1082
- if ( RELEVANSSI_PREMIUM ) {
1083
- esc_html_e( 'Enable this option to use PDF content for excerpts.', 'relevanssi' );
1084
- }
1085
- ?>
1086
- </p>
1087
-
1088
- <p class="description"><?php esc_html_e( 'Current custom field setting', 'relevanssi' ); ?>:
1089
- <?php
1090
- if ( 'visible' === $index_fields ) {
1091
- esc_html_e( 'all visible custom fields', 'relevanssi' );
1092
- } elseif ( 'all' === $index_fields ) {
1093
- esc_html_e( 'all custom fields', 'relevanssi' );
1094
- } elseif ( ! empty( $index_fields ) ) {
1095
- printf( '<code>%s</code>', esc_html( $index_fields ) );
1096
- } elseif ( RELEVANSSI_PREMIUM ) {
1097
- esc_html_e( 'Just PDF content', 'relevanssi' );
1098
  } else {
1099
- esc_html_e( 'None selected', 'relevanssi' );
 
1100
  }
1101
- ?>
1102
- </p>
1103
- </td>
1104
- </tr>
1105
- </table>
1106
-
1107
- <h2><?php esc_html_e( 'Search hit highlighting', 'relevanssi' ); ?></h2>
1108
-
1109
- <table id="relevanssi_highlighting" class="form-table
1110
- <?php
1111
- if ( empty( $excerpts ) ) {
1112
- echo 'relevanssi_disabled';
1113
  }
1114
- ?>
1115
- ">
1116
- <tr>
1117
- <th scope="row">
1118
- <label for='relevanssi_highlight'><?php esc_html_e( 'Highlight type', 'relevanssi' ); ?></label>
1119
- </th>
1120
- <td>
1121
- <select name='relevanssi_highlight' id='relevanssi_highlight'
1122
- <?php
1123
- if ( empty( $excerpts ) ) {
1124
- echo "disabled='disabled'";
1125
- }
1126
- ?>
1127
- >
1128
- <option value='no' <?php echo esc_html( $highlight_none ); ?>><?php esc_html_e( 'No highlighting', 'relevanssi' ); ?></option>
1129
- <option value='mark' <?php echo esc_html( $highlight_mark ); ?>>&lt;mark&gt;</option>
1130
- <option value='em' <?php echo esc_html( $highlight_em ); ?>>&lt;em&gt;</option>
1131
- <option value='strong' <?php echo esc_html( $highlight_strong ); ?>>&lt;strong&gt;</option>
1132
- <option value='col' <?php echo esc_html( $highlight_col ); ?>><?php esc_html_e( 'Text color', 'relevanssi' ); ?></option>
1133
- <option value='bgcol' <?php echo esc_html( $highlight_bgcol ); ?>><?php esc_html_e( 'Background color', 'relevanssi' ); ?></option>
1134
- <option value='css' <?php echo esc_html( $highlight_style ); ?>><?php esc_html_e( 'CSS Style', 'relevanssi' ); ?></option>
1135
- <option value='class' <?php echo esc_html( $highlight_class ); ?>><?php esc_html_e( 'CSS Class', 'relevanssi' ); ?></option>
1136
- </select>
1137
- <p class="description"><?php esc_html_e( 'Requires custom snippets to work.', 'relevanssi' ); ?></p>
1138
- </td>
1139
- </tr>
1140
- <tr id="relevanssi_txt_col" class='<?php echo esc_attr( $txt_col_display ); ?>'>
1141
- <th scope="row">
1142
- <label for="relevanssi_txt_col"><?php esc_html_e( 'Text color', 'relevanssi' ); ?></label>
1143
- </th>
1144
- <td>
1145
- <input type='text' name='relevanssi_txt_col' id='relevanssi_txt_col' size='7' class="color-field" data-default-color="#ff0000" value='<?php echo esc_attr( $txt_col ); ?>'
1146
- <?php
1147
- if ( empty( $excerpts ) ) {
1148
- echo "disabled='disabled'";
1149
- }
1150
- ?>
1151
- />
1152
- </td>
1153
- </tr>
1154
- <tr id="relevanssi_bg_col" class=' <?php echo esc_attr( $bg_col_display ); ?>'>
1155
- <th scope="row">
1156
- <label for="relevanssi_bg_col"><?php esc_html_e( 'Background color', 'relevanssi' ); ?></label>
1157
- </th>
1158
- <td>
1159
- <input type='text' name='relevanssi_bg_col' id='relevanssi_bg_col' size='7' class="color-field" data-default-color="#ffaf75" value='<?php echo esc_attr( $bg_col ); ?>'
1160
- <?php
1161
- if ( empty( $excerpts ) ) {
1162
- echo "disabled='disabled'";
1163
- }
1164
- ?>
1165
- />
1166
- </td>
1167
- </tr>
1168
- <tr id="relevanssi_css" class=' <?php echo esc_attr( $css_display ); ?>'>
1169
- <th scope="row">
1170
- <label for='relevanssi_css'><?php esc_html_e( 'CSS style for highlights', 'relevanssi' ); ?></label>
1171
- </th>
1172
- <td>
1173
- <input type='text' name='relevanssi_css' id='relevanssi_css' size='60' value='<?php echo esc_attr( $css ); ?>'
1174
- <?php
1175
- if ( empty( $excerpts ) ) {
1176
- echo "disabled='disabled'";
1177
- }
1178
- ?>
1179
- />
1180
- <?php // Translators: %s is a <span> tag. ?>
1181
- <p class="description"><?php printf( esc_html__( 'The highlights will be wrapped in a %s with this CSS in the style parameter.', 'relevanssi' ), '&lt;span&gt;' ); ?></p>
1182
- </td>
1183
- </tr>
1184
- <tr id="relevanssi_class" class=' <?php echo esc_attr( $class_display ); ?>'>
1185
- <th scope="row">
1186
- <label for='relevanssi_class'><?php esc_html_e( 'CSS class for highlights', 'relevanssi' ); ?></label>
1187
- </th>
1188
- <td>
1189
- <input type='text' name='relevanssi_class' id='relevanssi_class' size='60' value='<?php echo esc_attr( $class ); ?>'
1190
- <?php
1191
- if ( empty( $excerpts ) ) {
1192
- echo "disabled='disabled'";
1193
- }
1194
- ?>
1195
- />
1196
- <?php // Translators: %s is a <span> tag. ?>
1197
- <p class="description"><?php printf( esc_html__( 'The highlights will be wrapped in a %s with this class.', 'relevanssi' ), '&lt;span&gt;' ); ?></p>
1198
- </td>
1199
- </tr>
1200
- <tr>
1201
- <th scope="row">
1202
- <label for='relevanssi_hilite_title'><?php esc_html_e( 'Highlight in titles', 'relevanssi' ); ?></label>
1203
- </th>
1204
- <td>
1205
- <fieldset>
1206
- <legend class="screen-reader-text"><?php esc_html_e( 'Highlight query terms in titles', 'relevanssi' ); ?></legend>
1207
- <label for='relevanssi_hilite_title'>
1208
- <input type='checkbox' name='relevanssi_hilite_title' id='relevanssi_hilite_title' <?php echo esc_html( $highlight_title ); ?>
1209
- <?php
1210
- if ( empty( $excerpts ) ) {
1211
- echo "disabled='disabled'";
1212
- }
1213
- ?>
1214
- />
1215
- <?php esc_html_e( 'Highlight query terms in titles', 'relevanssi' ); ?>
1216
- </label>
1217
- </fieldset>
1218
- <?php // Translators: %1$s is 'the_title()', %2$s is 'relevanssi_the_title()'. ?>
1219
- <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>
1220
- </td>
1221
- </tr>
1222
- <tr>
1223
- <th scope="row">
1224
- <label for='relevanssi_highlight_docs'><?php esc_html_e( 'Highlight in documents', 'relevanssi' ); ?></label>
1225
- </th>
1226
- <td>
1227
- <fieldset>
1228
- <legend class="screen-reader-text"><?php esc_html_e( 'Highlight query terms in documents', 'relevanssi' ); ?></legend>
1229
- <label for='relevanssi_highlight_docs'>
1230
- <input type='checkbox' name='relevanssi_highlight_docs' id='relevanssi_highlight_docs' <?php echo esc_html( $highlight_docs ); ?>
1231
- <?php
1232
- if ( empty( $excerpts ) ) {
1233
- echo "disabled='disabled'";
1234
- }
1235
- ?>
1236
- />
1237
- <?php esc_html_e( 'Highlight query terms in documents', 'relevanssi' ); ?>
1238
- </label>
1239
- </fieldset>
1240
- <?php // Translators: %s is 'highlight'. ?>
1241
- <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>
1242
- </td>
1243
- </tr>
1244
- <tr>
1245
- <th scope="row">
1246
- <label for='relevanssi_highlight_comments'><?php esc_html_e( 'Highlight in comments', 'relevanssi' ); ?></label>
1247
- </th>
1248
- <td>
1249
- <fieldset>
1250
- <legend class="screen-reader-text"><?php esc_html_e( 'Highlight query terms in comments', 'relevanssi' ); ?></legend>
1251
- <label for='relevanssi_highlight_comments'>
1252
- <input type='checkbox' name='relevanssi_highlight_comments' id='relevanssi_highlight_comments' <?php echo esc_html( $highlight_coms ); ?>
1253
- <?php
1254
- if ( empty( $excerpts ) ) {
1255
- echo "disabled='disabled'";
1256
- }
1257
- ?>
1258
- />
1259
- <?php esc_html_e( 'Highlight query terms in comments', 'relevanssi' ); ?>
1260
- </label>
1261
- </fieldset>
1262
- <p class="description"><?php esc_html_e( 'Highlights hits in comments when user opens the post from search results.', 'relevanssi' ); ?></p>
1263
- </td>
1264
- </tr>
1265
- <tr>
1266
- <th scope="row">
1267
- <label for='relevanssi_word_boundaries'><?php esc_html_e( 'Highlighting problems with non-ASCII alphabet?', 'relevanssi' ); ?></label>
1268
- </th>
1269
- <td>
1270
- <fieldset>
1271
- <legend class="screen-reader-text"><?php esc_html_e( 'Uncheck this if you use non-ASCII characters', 'relevanssi' ); ?></legend>
1272
- <label for='relevanssi_word_boundaries'>
1273
- <input type='checkbox' name='relevanssi_word_boundaries' id='relevanssi_word_boundaries' <?php echo esc_html( $word_boundaries ); ?>
1274
- <?php
1275
- if ( empty( $excerpts ) ) {
1276
- echo "disabled='disabled'";
1277
- }
1278
- ?>
1279
- />
1280
- <?php esc_html_e( 'Uncheck this if you use non-ASCII characters', 'relevanssi' ); ?>
1281
- </label>
1282
- </fieldset>
1283
- <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>
1284
- </td>
1285
- </tr>
1286
- </table>
1287
-
1288
- <h2><?php esc_html_e( 'Breakdown of search results', 'relevanssi' ); ?></h2>
1289
-
1290
- <table id="relevanssi_breakdown" class="form-table
1291
- <?php
1292
- if ( empty( $excerpts ) ) {
1293
- echo 'relevanssi_disabled';
1294
  }
1295
- ?>
1296
- ">
1297
- <tr>
1298
- <th scope="row">
1299
- <label for='relevanssi_show_matches'><?php esc_html_e( 'Breakdown of search hits in excerpts', 'relevanssi' ); ?></label>
1300
- </th>
1301
- <td>
1302
- <fieldset>
1303
- <legend class="screen-reader-text"><?php esc_html_e( 'Show the breakdown of search hits in the excerpts', 'relevanssi' ); ?></legend>
1304
- <label for='relevanssi_show_matches'>
1305
- <input type='checkbox' name='relevanssi_show_matches' id='relevanssi_show_matches' <?php echo esc_html( $show_matches ); ?>
1306
- <?php
1307
- if ( empty( $excerpts ) ) {
1308
- echo "disabled='disabled'";
1309
- }
1310
- ?>
1311
- />
1312
- <?php esc_html_e( 'Show the breakdown of search hits in the excerpts.', 'relevanssi' ); ?>
1313
- </label>
1314
- </fieldset>
1315
- <p class="description"><?php esc_html_e( 'Requires custom snippets to work.', 'relevanssi' ); ?></p>
1316
- </td>
1317
- </tr>
1318
- <tr>
1319
- <th scope="row">
1320
- <label for='relevanssi_show_matches_text'><?php esc_html_e( 'The breakdown format', 'relevanssi' ); ?></label>
1321
- </th>
1322
- <td>
1323
- <textarea name='relevanssi_show_matches_text' id='relevanssi_show_matches_text' cols="80" rows="4"
1324
- <?php
1325
- if ( empty( $excerpts ) ) {
1326
- echo "disabled='disabled'";
1327
- }
1328
- ?>
1329
- ><?php echo esc_attr( $show_matches_text ); ?></textarea>
1330
- <p class="description"><?php esc_html_e( 'Use %body%, %title%, %tags% and %comments% to display the number of hits (in different parts of the post), %total% for total hits, %score% to display the document weight and %terms% to show how many hits each search term got.', 'relevanssi' ); /* phpcs:ignore WordPress.WP.I18n */ ?></p>
1331
- </td>
1332
- </tr>
1333
- </table>
1334
-
1335
- <?php endif; // Active tab: excerpts & highlights. ?>
1336
-
1337
- <?php
1338
- if ( 'indexing' === $active_tab ) {
1339
- require_once 'tabs/indexing-tab.php';
1340
- relevanssi_indexing_tab();
1341
  }
1342
- ?>
1343
-
1344
- <?php if ( 'attachments' === $active_tab ) : ?>
1345
-
1346
- <?php
1347
- if ( function_exists( 'relevanssi_form_attachments' ) ) {
1348
- relevanssi_form_attachments();
1349
- } else {
1350
- $display_save_button = false;
1351
- ?>
1352
-
1353
- <h2><?php esc_html_e( 'Indexing attachment content', 'relevanssi' ); ?></h2>
1354
-
1355
- <p><?php esc_html_e( 'With Relevanssi Premium, you can index the text contents of attachments (PDFs, Word documents, Open Office documents and many other types). The contents of the attachments are processed on an external service, which makes the feature reliable and light on your own server performance.', 'relevanssi' ); ?></p>
1356
- <?php // Translators: %1$s starts the link, %2$s closes it. ?>
1357
- <p><?php printf( esc_html__( 'In order to access this and many other delightful Premium features, %1$sbuy Relevanssi Premium here%2$s.', 'relevanssi' ), '<a href="https://www.relevanssi.com/buy-premium/">', '</a>' ); ?></p>
1358
-
1359
- <?php } ?>
1360
-
1361
- <?php endif; // Active tab: attachments. ?>
1362
-
1363
- <?php if ( 'synonyms' === $active_tab ) : ?>
1364
-
1365
- <h3 id="synonyms"><?php esc_html_e( 'Synonyms', 'relevanssi' ); ?></h3>
1366
-
1367
- <table class="form-table">
1368
- <tr>
1369
- <th scope="row">
1370
- <?php esc_html_e( 'Synonyms', 'relevanssi' ); ?>
1371
- </th>
1372
- <td>
1373
- <p class="description"><?php esc_html_e( 'Add synonyms here to make the searches find better results. If you notice your users frequently misspelling a product name, or for other reasons use many names for one thing, adding synonyms will make the results better.', 'relevanssi' ); ?></p>
1374
-
1375
- <p class="description"><?php esc_html_e( "Do not go overboard, though, as too many synonyms can make the search confusing: users understand if a search query doesn't match everything, but they get confused if the searches match to unexpected things.", 'relevanssi' ); ?></p>
1376
- <br />
1377
- <textarea name='relevanssi_synonyms' id='relevanssi_synonyms' rows='9' cols='60'><?php echo esc_textarea( htmlspecialchars( $synonyms ) ); ?></textarea>
1378
-
1379
- <p class="description"><?php _e( 'The format here is <code>key = value</code>. If you add <code>dog = hound</code> to the list of synonyms, searches for <code>dog</code> automatically become a search for <code>dog hound</code> and will thus match to posts that include either <code>dog</code> or <code>hound</code>. This only works in OR searches: in AND searches the synonyms only restrict the search, as now the search only finds posts that contain <strong>both</strong> <code>dog</code> and <code>hound</code>.', 'relevanssi' ); // WPCS: XSS ok. ?></p>
1380
-
1381
- <p class="description"><?php _e( 'The synonyms are one direction only. If you want both directions, add the synonym again, reversed: <code>hound = dog</code>.', 'relevanssi' ); // WPCS: XSS ok. ?></p>
1382
-
1383
- <p class="description"><?php _e( "It's possible to use phrases for the value, but not for the key. <code>dog = \"great dane\"</code> works, but <code>\"great dane\" = dog</code> doesn't.", 'relevanssi' ); // WPCS: XSS ok. ?></p>
1384
-
1385
- <?php if ( RELEVANSSI_PREMIUM ) : ?>
1386
- <p class="description"><?php esc_html_e( 'If you want to use synonyms in AND searches, enable synonym indexing on the Indexing tab.', 'relevanssi' ); ?></p>
1387
- <?php endif; ?>
1388
- </td>
1389
- </tr>
1390
- </table>
1391
-
1392
- <?php endif; // Active tab: synonyms. ?>
1393
-
1394
- <?php if ( 'stopwords' === $active_tab ) : ?>
1395
-
1396
- <h3 id="stopwords"><?php esc_html_e( 'Stopwords', 'relevanssi' ); ?></h3>
1397
-
1398
- <?php relevanssi_show_stopwords(); ?>
1399
-
1400
- <?php
1401
- /**
1402
- * Filters whether the common words list is displayed or not.
1403
- *
1404
- * The list of 25 most common words is displayed by default, but if the index is
1405
- * big, displaying the list can take a long time. This filter can be used to
1406
- * turn the list off.
1407
- *
1408
- * @param boolean If true, show the list; if false, don't show it.
1409
- */
1410
- if ( apply_filters( 'relevanssi_display_common_words', true ) ) {
1411
- relevanssi_common_words( 25 );
1412
  }
1413
- ?>
1414
-
1415
- <?php endif; // Active tab: stopwords. ?>
1416
-
1417
- <?php if ( 'importexport' === $active_tab ) : ?>
1418
 
1419
- <?php
1420
- if ( function_exists( 'relevanssi_form_importexport' ) ) {
1421
- relevanssi_form_importexport();
1422
- }
1423
  ?>
1424
 
1425
- <?php endif; ?>
1426
-
1427
- <?php if ( $display_save_button ) : ?>
1428
-
1429
  <input type='submit' name='submit' value='<?php esc_attr_e( 'Save the options', 'relevanssi' ); ?>' class='button button-primary' />
1430
 
1431
  <?php endif; ?>
@@ -1436,73 +793,6 @@ if ( function_exists( 'relevanssi_form_hide_post_controls' ) ) {
1436
  <?php
1437
  }
1438
 
1439
- /**
1440
- * Displays a list of stopwords.
1441
- *
1442
- * Displays the list of stopwords and gives the controls for adding new stopwords.
1443
- *
1444
- * @global object $wpdb The WP database interface.
1445
- * @global array $relevanssi_variables The global Relevanssi variables array.
1446
- */
1447
- function relevanssi_show_stopwords() {
1448
- global $wpdb, $relevanssi_variables;
1449
-
1450
- $plugin = 'relevanssi';
1451
- if ( RELEVANSSI_PREMIUM ) {
1452
- $plugin = 'relevanssi-premium';
1453
- }
1454
-
1455
- 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' ) );
1456
- ?>
1457
- <table class="form-table">
1458
- <tr>
1459
- <th scope="row">
1460
- <label for="addstopword"><p><?php esc_html_e( 'Stopword(s) to add', 'relevanssi' ); ?>
1461
- </th>
1462
- <td>
1463
- <textarea name="addstopword" id="addstopword" rows="2" cols="80"></textarea>
1464
- <p><input type="submit" value="<?php esc_attr_e( 'Add', 'relevanssi' ); ?>" class='button' /></p>
1465
- </td>
1466
- </tr>
1467
- </table>
1468
- <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>
1469
-
1470
- <table class="form-table">
1471
- <tr>
1472
- <th scope="row">
1473
- <?php esc_html_e( 'Current stopwords', 'relevanssi' ); ?>
1474
- </th>
1475
- <td>
1476
- <?php
1477
- echo '<ul>';
1478
- $results = $wpdb->get_results( 'SELECT * FROM ' . $relevanssi_variables['stopword_table'] ); // WPCS: unprepared SQL ok, Relevanssi table name.
1479
- $exportlist = array();
1480
- foreach ( $results as $stopword ) {
1481
- $sw = stripslashes( $stopword->stopword );
1482
- printf( '<li style="display: inline;"><input type="submit" name="removestopword" value="%s"/></li>', esc_attr( $sw ) );
1483
- array_push( $exportlist, $sw );
1484
- }
1485
- echo '</ul>';
1486
-
1487
- $exportlist = htmlspecialchars( implode( ', ', $exportlist ) );
1488
- ?>
1489
- <p><input type="submit" id="removeallstopwords" name="removeallstopwords" value="<?php esc_attr_e( 'Remove all stopwords', 'relevanssi' ); ?>" class='button' /></p>
1490
- </td>
1491
- </tr>
1492
- <tr>
1493
- <th scope="row">
1494
- <?php esc_html_e( 'Exportable list of stopwords', 'relevanssi' ); ?>
1495
- </th>
1496
- <td>
1497
- <textarea name="stopwords" id="stopwords" rows="2" cols="80"><?php echo esc_textarea( $exportlist ); ?></textarea>
1498
- <p class="description"><?php esc_html_e( 'You can copy the list of stopwords here if you want to back up the list, copy it to a different blog or otherwise need the list.', 'relevanssi' ); ?></p>
1499
- </td>
1500
- </tr>
1501
- </table>
1502
-
1503
- <?php
1504
- }
1505
-
1506
  /**
1507
  * Displays the contextual help menu.
1508
  *
@@ -1630,6 +920,7 @@ function rlv_index_filter( $block, $post_id ) {
1630
  '<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>' .
1631
  // Translators: %s is the Knowledge Base URL.
1632
  '<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>' .
 
1633
  '</ul>',
1634
  ));
1635
  $screen->add_help_tab( array(
479
  return $result;
480
  }
481
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
482
  /**
483
  * Shows the query log with the most common queries
484
  *
696
  wp_enqueue_script( 'dashboard' );
697
  wp_print_scripts( 'dashboard' );
698
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
699
  echo "<div class='postbox-container'>";
700
  echo "<form method='post'>";
701
 
731
  <?php endif; ?>
732
  </h2>
733
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
734
  <?php
735
+ if ( 'overview' === $active_tab ) {
736
+ if ( ! RELEVANSSI_PREMIUM ) {
737
+ $display_save_button = false;
738
+ }
739
+ require_once 'tabs/overview-tab.php';
740
+ relevanssi_overview_tab();
741
+ }
742
  if ( 'logging' === $active_tab ) {
743
  require_once 'tabs/logging-tab.php';
744
  relevanssi_logging_tab();
747
  require_once 'tabs/searching-tab.php';
748
  relevanssi_searching_tab();
749
  }
750
+ if ( 'excerpts' === $active_tab ) {
751
+ require_once 'tabs/excerpts-tab.php';
752
+ relevanssi_excerpts_tab();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
753
  }
754
+ if ( 'indexing' === $active_tab ) {
755
+ require_once 'tabs/indexing-tab.php';
756
+ relevanssi_indexing_tab();
757
+ }
758
+ if ( 'attachments' === $active_tab ) {
759
+ if ( ! RELEVANSSI_PREMIUM ) {
760
+ $display_save_button = false;
761
+ require_once 'tabs/attachments-tab.php';
762
+ relevanssi_attachments_tab();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
763
  } else {
764
+ require_once dirname( $relevanssi_variables['file'] ) . '/premium/tabs/attachments-tab.php';
765
+ relevanssi_attachments_tab();
766
  }
 
 
 
 
 
 
 
 
 
 
 
 
767
  }
768
+ if ( 'synonyms' === $active_tab ) {
769
+ require_once 'tabs/synonyms-tab.php';
770
+ relevanssi_synonyms_tab();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
771
  }
772
+ if ( 'stopwords' === $active_tab ) {
773
+ require_once 'tabs/stopwords-tab.php';
774
+ relevanssi_stopwords_tab();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
775
  }
776
+ if ( 'importexport' === $active_tab ) {
777
+ if ( RELEVANSSI_PREMIUM ) {
778
+ require_once dirname( $relevanssi_variables['file'] ) . '/premium/tabs/import-export-tab.php';
779
+ relevanssi_import_export_tab();
780
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
781
  }
 
 
 
 
 
782
 
783
+ if ( $display_save_button ) :
 
 
 
784
  ?>
785
 
 
 
 
 
786
  <input type='submit' name='submit' value='<?php esc_attr_e( 'Save the options', 'relevanssi' ); ?>' class='button button-primary' />
787
 
788
  <?php endif; ?>
793
  <?php
794
  }
795
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
796
  /**
797
  * Displays the contextual help menu.
798
  *
920
  '<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>' .
921
  // Translators: %s is the Knowledge Base URL.
922
  '<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>' .
923
+ '<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>' .
924
  '</ul>',
925
  ));
926
  $screen->add_help_tab( array(
lib/search.php CHANGED
@@ -725,21 +725,26 @@ function relevanssi_search( $args ) {
725
  $match->doc = '**' . $match->type . '**' . $match->item;
726
  }
727
 
728
- if ( isset( $match->taxonomy_detail ) ) {
729
- $match->taxonomy_score = 0;
730
- $match->taxonomy_detail = json_decode( $match->taxonomy_detail );
731
- if ( is_object( $match->taxonomy_detail ) ) {
732
- foreach ( $match->taxonomy_detail as $tax => $count ) {
733
- if ( 'post_tag' === $tax ) {
734
- $match->tag = $count;
735
- }
736
- if ( empty( $post_type_weights[ $tax ] ) ) {
737
- $match->taxonomy_score += $count * 1;
738
- } else {
739
- $match->taxonomy_score += $count * $post_type_weights[ $tax ];
740
- }
741
- }
742
  }
 
 
 
 
 
 
 
743
  }
744
 
745
  $match->tf =
@@ -2136,3 +2141,29 @@ function relevanssi_generate_term_cond( $term, $o_term_cond ) {
2136
 
2137
  return $term_cond;
2138
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
725
  $match->doc = '**' . $match->type . '**' . $match->item;
726
  }
727
 
728
+ if ( ! empty( $match->taxonomy_detail ) ) {
729
+ relevanssi_taxonomy_score( $match, $post_type_weights );
730
+ } else {
731
+ // This shouldn't really happen, but let's still have a backup.
732
+ $tag_weight = 1;
733
+ if ( isset( $post_type_weights['post_tag'] ) ) {
734
+ $tag_weight = $post_type_weights['post_tag'];
735
+ }
736
+
737
+ $category_weight = 1;
738
+ if ( isset( $post_type_weights['category'] ) ) {
739
+ $category_weight = $post_type_weights['category'];
 
 
740
  }
741
+
742
+ $taxonomy_weight = 1;
743
+
744
+ $match->taxonomy_score =
745
+ $match->tag * $tag_weight +
746
+ $match->category * $category_weight +
747
+ $match->taxonomy * $taxonomy_weight;
748
  }
749
 
750
  $match->tf =
2141
 
2142
  return $term_cond;
2143
  }
2144
+
2145
+ /**
2146
+ * Counts the taxonomy score for a match.
2147
+ *
2148
+ * Uses the taxonomy_detail object to count the taxonomy score for a match.
2149
+ * If there's a taxonomy weight in $post_type_weights, that is used, otherwise
2150
+ * assume weight 1.
2151
+ *
2152
+ * @since 2.1.5
2153
+ *
2154
+ * @param object $match The match object, used as a reference.
2155
+ * @param array $post_type_weights The post type and taxonomy weights array.
2156
+ */
2157
+ function relevanssi_taxonomy_score( &$match, $post_type_weights ) {
2158
+ $match->taxonomy_score = 0;
2159
+ $match->taxonomy_detail = json_decode( $match->taxonomy_detail );
2160
+ if ( is_object( $match->taxonomy_detail ) ) {
2161
+ foreach ( $match->taxonomy_detail as $tax => $count ) {
2162
+ if ( empty( $post_type_weights[ $tax ] ) ) {
2163
+ $match->taxonomy_score += $count * 1;
2164
+ } else {
2165
+ $match->taxonomy_score += $count * $post_type_weights[ $tax ];
2166
+ }
2167
+ }
2168
+ }
2169
+ }
lib/tabs/attachments-tab.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * /lib/tabs/attachments-tab.php
4
+ *
5
+ * Prints out the Attachments tab in Relevanssi settings.
6
+ *
7
+ * @package Relevanssi
8
+ * @author Mikko Saari
9
+ * @license https://wordpress.org/about/gpl/ GNU General Public License
10
+ * @see https://www.relevanssi.com/
11
+ */
12
+
13
+ /**
14
+ * Prints out the attachments tab in Relevanssi settings.
15
+ */
16
+ function relevanssi_attachments_tab() {
17
+ ?>
18
+ <h2><?php esc_html_e( 'Indexing attachment content', 'relevanssi' ); ?></h2>
19
+
20
+ <p><?php esc_html_e( 'With Relevanssi Premium, you can index the text contents of attachments (PDFs, Word documents, Open Office documents and many other types). The contents of the attachments are processed on an external service, which makes the feature reliable and light on your own server performance.', 'relevanssi' ); ?></p>
21
+ <?php // Translators: %1$s starts the link, %2$s closes it. ?>
22
+ <p><?php printf( esc_html__( 'In order to access this and many other delightful Premium features, %1$sbuy Relevanssi Premium here%2$s.', 'relevanssi' ), '<a href="https://www.relevanssi.com/buy-premium/">', '</a>' ); ?></p>
23
+ <?php
24
+ }
lib/tabs/excerpts-tab.php ADDED
@@ -0,0 +1,435 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * /lib/tabs/excerpts-tab.php
4
+ *
5
+ * Prints out the Excerpts tab in Relevanssi settings.
6
+ *
7
+ * @package Relevanssi
8
+ * @author Mikko Saari
9
+ * @license https://wordpress.org/about/gpl/ GNU General Public License
10
+ * @see https://www.relevanssi.com/
11
+ */
12
+
13
+ /**
14
+ * Prints out the excerpts tab in Relevanssi settings.
15
+ */
16
+ function relevanssi_excerpts_tab() {
17
+ $excerpts = get_option( 'relevanssi_excerpts' );
18
+ $excerpt_length = get_option( 'relevanssi_excerpt_length' );
19
+ $excerpt_type = get_option( 'relevanssi_excerpt_type' );
20
+ $excerpt_allowable_tags = get_option( 'relevanssi_excerpt_allowable_tags' );
21
+ $excerpt_custom_fields = get_option( 'relevanssi_excerpt_custom_fields' );
22
+ $highlight = get_option( 'relevanssi_highlight' );
23
+ $txt_col = get_option( 'relevanssi_txt_col' );
24
+ $bg_col = get_option( 'relevanssi_bg_col' );
25
+ $css = get_option( 'relevanssi_css' );
26
+ $class = get_option( 'relevanssi_class' );
27
+ $highlight_title = get_option( 'relevanssi_hilite_title' );
28
+ $highlight_docs = get_option( 'relevanssi_highlight_docs' );
29
+ $highlight_coms = get_option( 'relevanssi_highlight_comments' );
30
+ $show_matches = get_option( 'relevanssi_show_matches' );
31
+ $show_matches_text = get_option( 'relevanssi_show_matches_text' );
32
+ $word_boundaries = get_option( 'relevanssi_word_boundaries' );
33
+ $index_fields = get_option( 'relevanssi_index_fields' );
34
+
35
+ if ( '#' !== substr( $txt_col, 0, 1 ) ) {
36
+ $txt_col = '#' . $txt_col;
37
+ }
38
+ $txt_col = relevanssi_sanitize_hex_color( $txt_col );
39
+ if ( '#' !== substr( $bg_col, 0, 1 ) ) {
40
+ $bg_col = '#' . $bg_col;
41
+ }
42
+ $bg_col = relevanssi_sanitize_hex_color( $bg_col );
43
+
44
+ $show_matches_text = stripslashes( $show_matches_text );
45
+
46
+ $excerpts = relevanssi_check( $excerpts );
47
+ $excerpt_custom_fields = relevanssi_check( $excerpt_custom_fields );
48
+ $highlight_title = relevanssi_check( $highlight_title );
49
+ $highlight_docs = relevanssi_check( $highlight_docs );
50
+ $highlight_coms = relevanssi_check( $highlight_coms );
51
+ $show_matches = relevanssi_check( $show_matches );
52
+ $word_boundaries = relevanssi_check( $word_boundaries );
53
+ $excerpt_chars = relevanssi_select( $excerpt_type, 'chars' );
54
+ $excerpt_words = relevanssi_select( $excerpt_type, 'words' );
55
+ $highlight_none = relevanssi_select( $highlight, 'no' );
56
+ $highlight_mark = relevanssi_select( $highlight, 'mark' );
57
+ $highlight_em = relevanssi_select( $highlight, 'em' );
58
+ $highlight_strong = relevanssi_select( $highlight, 'strong' );
59
+ $highlight_col = relevanssi_select( $highlight, 'col' );
60
+ $highlight_bgcol = relevanssi_select( $highlight, 'bgcol' );
61
+ $highlight_style = relevanssi_select( $highlight, 'style' );
62
+ $highlight_class = relevanssi_select( $highlight, 'class' );
63
+
64
+ $txt_col_display = 'screen-reader-text';
65
+ $bg_col_display = 'screen-reader-text';
66
+ $css_display = 'screen-reader-text';
67
+ $class_display = 'screen-reader-text';
68
+
69
+ if ( 'col' === $highlight ) {
70
+ $txt_col_display = '';
71
+ }
72
+ if ( 'bgcol' === $highlight ) {
73
+ $bg_col_display = '';
74
+ }
75
+ if ( 'style' === $highlight ) {
76
+ $css_display = '';
77
+ }
78
+ if ( 'class' === $highlight ) {
79
+ $class_display = '';
80
+ }
81
+
82
+ ?>
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
+ <label for='relevanssi_excerpts'><?php esc_html_e( 'Custom search result snippets', 'relevanssi' ); ?></label>
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
+ </td>
101
+ </tr>
102
+ <tr id="tr_excerpt_length"
103
+ <?php
104
+ if ( empty( $excerpts ) ) {
105
+ echo "class='relevanssi_disabled'";
106
+ }
107
+ ?>
108
+ >
109
+ <th scope="row">
110
+ <label for='relevanssi_excerpt_length'><?php esc_html_e( 'Length of the snippet', 'relevanssi' ); ?></label>
111
+ </th>
112
+ <td>
113
+ <input type='text' name='relevanssi_excerpt_length' id='relevanssi_excerpt_length' size='4' value='<?php echo esc_attr( $excerpt_length ); ?>'
114
+ <?php
115
+ if ( empty( $excerpts ) ) {
116
+ echo "disabled='disabled'";
117
+ }
118
+ ?>
119
+ />
120
+ <select name='relevanssi_excerpt_type' id='relevanssi_excerpt_type'
121
+ <?php
122
+ if ( empty( $excerpts ) ) {
123
+ echo "disabled='disabled'";
124
+ }
125
+ ?>
126
+ >
127
+ <option value='chars' <?php echo esc_html( $excerpt_chars ); ?>><?php esc_html_e( 'characters', 'relevanssi' ); ?></option>
128
+ <option value='words' <?php echo esc_html( $excerpt_words ); ?>><?php esc_html_e( 'words', 'relevanssi' ); ?></option>
129
+ </select>
130
+ <p class="description"><?php esc_html_e( "Using words is much faster than characters. Don't use characters, unless you have a really good reason and your posts are short.", 'relevanssi' ); ?></p>
131
+ </td>
132
+ </tr>
133
+ <tr id="tr_excerpt_allowable_tags"
134
+ <?php
135
+ if ( empty( $excerpts ) ) {
136
+ echo "class='relevanssi_disabled'";
137
+ }
138
+ ?>
139
+ >
140
+ <th scope="row">
141
+ <label for='relevanssi_excerpt_allowable_tags'><?php esc_html_e( 'Allowable tags in excerpts', 'relevanssi' ); ?></label>
142
+ </th>
143
+ <td>
144
+ <input type='text' name='relevanssi_excerpt_allowable_tags' id='relevanssi_excerpt_allowable_tags' size='60' value='<?php echo esc_attr( $excerpt_allowable_tags ); ?>'
145
+ <?php
146
+ if ( empty( $excerpts ) ) {
147
+ echo "disabled='disabled'";
148
+ }
149
+ ?>
150
+ />
151
+ <p class="description"><?php esc_html_e( 'List all tags you want to allow in excerpts. For example: &lt;p&gt;&lt;a&gt;&lt;strong&gt;.', 'relevanssi' ); ?></p>
152
+ </td>
153
+ </tr>
154
+ <tr id="tr_excerpt_custom_fields"
155
+ <?php
156
+ if ( empty( $excerpts ) ) {
157
+ echo "class='relevanssi_disabled'";
158
+ }
159
+ ?>
160
+ >
161
+ <th scope="row">
162
+ <label for='relevanssi_excerpt_custom_fields'><?php esc_html_e( 'Use custom fields for excerpts', 'relevanssi' ); ?></label>
163
+ </th>
164
+ <td>
165
+ <fieldset>
166
+ <legend class="screen-reader-text"><?php esc_html_e( 'Use custom field content for building excerpts', 'relevanssi' ); ?></legend>
167
+ <label>
168
+ <input type='checkbox' name='relevanssi_excerpt_custom_fields' id='relevanssi_excerpt_custom_fields' <?php echo esc_html( $excerpt_custom_fields ); ?>
169
+ <?php
170
+ if ( empty( $excerpts ) || empty( $index_fields ) ) {
171
+ echo "disabled='disabled'";
172
+ }
173
+ ?>
174
+ />
175
+ <?php esc_html_e( 'Use custom field content for building excerpts', 'relevanssi' ); ?>
176
+ </label>
177
+ </fieldset>
178
+ <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' ); ?>
179
+ <?php
180
+ if ( RELEVANSSI_PREMIUM ) {
181
+ esc_html_e( 'Enable this option to use PDF content for excerpts.', 'relevanssi' );
182
+ }
183
+ ?>
184
+ </p>
185
+
186
+ <p class="description"><?php esc_html_e( 'Current custom field setting', 'relevanssi' ); ?>:
187
+ <?php
188
+ if ( 'visible' === $index_fields ) {
189
+ esc_html_e( 'all visible custom fields', 'relevanssi' );
190
+ } elseif ( 'all' === $index_fields ) {
191
+ esc_html_e( 'all custom fields', 'relevanssi' );
192
+ } elseif ( ! empty( $index_fields ) ) {
193
+ printf( '<code>%s</code>', esc_html( $index_fields ) );
194
+ } elseif ( RELEVANSSI_PREMIUM ) {
195
+ esc_html_e( 'Just PDF content', 'relevanssi' );
196
+ } else {
197
+ esc_html_e( 'None selected', 'relevanssi' );
198
+ }
199
+ ?>
200
+ </p>
201
+ </td>
202
+ </tr>
203
+ </table>
204
+
205
+ <h2><?php esc_html_e( 'Search hit highlighting', 'relevanssi' ); ?></h2>
206
+
207
+ <table id="relevanssi_highlighting" class="form-table
208
+ <?php
209
+ if ( empty( $excerpts ) ) {
210
+ echo 'relevanssi_disabled';
211
+ }
212
+ ?>
213
+ ">
214
+ <tr>
215
+ <th scope="row">
216
+ <label for='relevanssi_highlight'><?php esc_html_e( 'Highlight type', 'relevanssi' ); ?></label>
217
+ </th>
218
+ <td>
219
+ <select name='relevanssi_highlight' id='relevanssi_highlight'
220
+ <?php
221
+ if ( empty( $excerpts ) ) {
222
+ echo "disabled='disabled'";
223
+ }
224
+ ?>
225
+ >
226
+ <option value='no' <?php echo esc_html( $highlight_none ); ?>><?php esc_html_e( 'No highlighting', 'relevanssi' ); ?></option>
227
+ <option value='mark' <?php echo esc_html( $highlight_mark ); ?>>&lt;mark&gt;</option>
228
+ <option value='em' <?php echo esc_html( $highlight_em ); ?>>&lt;em&gt;</option>
229
+ <option value='strong' <?php echo esc_html( $highlight_strong ); ?>>&lt;strong&gt;</option>
230
+ <option value='col' <?php echo esc_html( $highlight_col ); ?>><?php esc_html_e( 'Text color', 'relevanssi' ); ?></option>
231
+ <option value='bgcol' <?php echo esc_html( $highlight_bgcol ); ?>><?php esc_html_e( 'Background color', 'relevanssi' ); ?></option>
232
+ <option value='css' <?php echo esc_html( $highlight_style ); ?>><?php esc_html_e( 'CSS Style', 'relevanssi' ); ?></option>
233
+ <option value='class' <?php echo esc_html( $highlight_class ); ?>><?php esc_html_e( 'CSS Class', 'relevanssi' ); ?></option>
234
+ </select>
235
+ <p class="description"><?php esc_html_e( 'Requires custom snippets to work.', 'relevanssi' ); ?></p>
236
+ </td>
237
+ </tr>
238
+ <tr id="relevanssi_txt_col" class='<?php echo esc_attr( $txt_col_display ); ?>'>
239
+ <th scope="row">
240
+ <label for="relevanssi_txt_col"><?php esc_html_e( 'Text color', 'relevanssi' ); ?></label>
241
+ </th>
242
+ <td>
243
+ <input type='text' name='relevanssi_txt_col' id='relevanssi_txt_col' size='7' class="color-field" data-default-color="#ff0000" value='<?php echo esc_attr( $txt_col ); ?>'
244
+ <?php
245
+ if ( empty( $excerpts ) ) {
246
+ echo "disabled='disabled'";
247
+ }
248
+ ?>
249
+ />
250
+ </td>
251
+ </tr>
252
+ <tr id="relevanssi_bg_col" class=' <?php echo esc_attr( $bg_col_display ); ?>'>
253
+ <th scope="row">
254
+ <label for="relevanssi_bg_col"><?php esc_html_e( 'Background color', 'relevanssi' ); ?></label>
255
+ </th>
256
+ <td>
257
+ <input type='text' name='relevanssi_bg_col' id='relevanssi_bg_col' size='7' class="color-field" data-default-color="#ffaf75" value='<?php echo esc_attr( $bg_col ); ?>'
258
+ <?php
259
+ if ( empty( $excerpts ) ) {
260
+ echo "disabled='disabled'";
261
+ }
262
+ ?>
263
+ />
264
+ </td>
265
+ </tr>
266
+ <tr id="relevanssi_css" class=' <?php echo esc_attr( $css_display ); ?>'>
267
+ <th scope="row">
268
+ <label for='relevanssi_css'><?php esc_html_e( 'CSS style for highlights', 'relevanssi' ); ?></label>
269
+ </th>
270
+ <td>
271
+ <input type='text' name='relevanssi_css' id='relevanssi_css' size='60' value='<?php echo esc_attr( $css ); ?>'
272
+ <?php
273
+ if ( empty( $excerpts ) ) {
274
+ echo "disabled='disabled'";
275
+ }
276
+ ?>
277
+ />
278
+ <?php // Translators: %s is a <span> tag. ?>
279
+ <p class="description"><?php printf( esc_html__( 'The highlights will be wrapped in a %s with this CSS in the style parameter.', 'relevanssi' ), '&lt;span&gt;' ); ?></p>
280
+ </td>
281
+ </tr>
282
+ <tr id="relevanssi_class" class=' <?php echo esc_attr( $class_display ); ?>'>
283
+ <th scope="row">
284
+ <label for='relevanssi_class'><?php esc_html_e( 'CSS class for highlights', 'relevanssi' ); ?></label>
285
+ </th>
286
+ <td>
287
+ <input type='text' name='relevanssi_class' id='relevanssi_class' size='60' value='<?php echo esc_attr( $class ); ?>'
288
+ <?php
289
+ if ( empty( $excerpts ) ) {
290
+ echo "disabled='disabled'";
291
+ }
292
+ ?>
293
+ />
294
+ <?php // Translators: %s is a <span> tag. ?>
295
+ <p class="description"><?php printf( esc_html__( 'The highlights will be wrapped in a %s with this class.', 'relevanssi' ), '&lt;span&gt;' ); ?></p>
296
+ </td>
297
+ </tr>
298
+ <tr>
299
+ <th scope="row">
300
+ <label for='relevanssi_hilite_title'><?php esc_html_e( 'Highlight in titles', 'relevanssi' ); ?></label>
301
+ </th>
302
+ <td>
303
+ <fieldset>
304
+ <legend class="screen-reader-text"><?php esc_html_e( 'Highlight query terms in titles', 'relevanssi' ); ?></legend>
305
+ <label for='relevanssi_hilite_title'>
306
+ <input type='checkbox' name='relevanssi_hilite_title' id='relevanssi_hilite_title' <?php echo esc_html( $highlight_title ); ?>
307
+ <?php
308
+ if ( empty( $excerpts ) ) {
309
+ echo "disabled='disabled'";
310
+ }
311
+ ?>
312
+ />
313
+ <?php esc_html_e( 'Highlight query terms in titles', 'relevanssi' ); ?>
314
+ </label>
315
+ </fieldset>
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>
319
+ </tr>
320
+ <tr>
321
+ <th scope="row">
322
+ <label for='relevanssi_highlight_docs'><?php esc_html_e( 'Highlight in documents', 'relevanssi' ); ?></label>
323
+ </th>
324
+ <td>
325
+ <fieldset>
326
+ <legend class="screen-reader-text"><?php esc_html_e( 'Highlight query terms in documents', 'relevanssi' ); ?></legend>
327
+ <label for='relevanssi_highlight_docs'>
328
+ <input type='checkbox' name='relevanssi_highlight_docs' id='relevanssi_highlight_docs' <?php echo esc_html( $highlight_docs ); ?>
329
+ <?php
330
+ if ( empty( $excerpts ) ) {
331
+ echo "disabled='disabled'";
332
+ }
333
+ ?>
334
+ />
335
+ <?php esc_html_e( 'Highlight query terms in documents', 'relevanssi' ); ?>
336
+ </label>
337
+ </fieldset>
338
+ <?php // Translators: %s is 'highlight'. ?>
339
+ <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>
340
+ </td>
341
+ </tr>
342
+ <tr>
343
+ <th scope="row">
344
+ <label for='relevanssi_highlight_comments'><?php esc_html_e( 'Highlight in comments', 'relevanssi' ); ?></label>
345
+ </th>
346
+ <td>
347
+ <fieldset>
348
+ <legend class="screen-reader-text"><?php esc_html_e( 'Highlight query terms in comments', 'relevanssi' ); ?></legend>
349
+ <label for='relevanssi_highlight_comments'>
350
+ <input type='checkbox' name='relevanssi_highlight_comments' id='relevanssi_highlight_comments' <?php echo esc_html( $highlight_coms ); ?>
351
+ <?php
352
+ if ( empty( $excerpts ) ) {
353
+ echo "disabled='disabled'";
354
+ }
355
+ ?>
356
+ />
357
+ <?php esc_html_e( 'Highlight query terms in comments', 'relevanssi' ); ?>
358
+ </label>
359
+ </fieldset>
360
+ <p class="description"><?php esc_html_e( 'Highlights hits in comments when user opens the post from search results.', 'relevanssi' ); ?></p>
361
+ </td>
362
+ </tr>
363
+ <tr>
364
+ <th scope="row">
365
+ <label for='relevanssi_word_boundaries'><?php esc_html_e( 'Highlighting problems with non-ASCII alphabet?', 'relevanssi' ); ?></label>
366
+ </th>
367
+ <td>
368
+ <fieldset>
369
+ <legend class="screen-reader-text"><?php esc_html_e( 'Uncheck this if you use non-ASCII characters', 'relevanssi' ); ?></legend>
370
+ <label for='relevanssi_word_boundaries'>
371
+ <input type='checkbox' name='relevanssi_word_boundaries' id='relevanssi_word_boundaries' <?php echo esc_html( $word_boundaries ); ?>
372
+ <?php
373
+ if ( empty( $excerpts ) ) {
374
+ echo "disabled='disabled'";
375
+ }
376
+ ?>
377
+ />
378
+ <?php esc_html_e( 'Uncheck this if you use non-ASCII characters', 'relevanssi' ); ?>
379
+ </label>
380
+ </fieldset>
381
+ <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>
382
+ </td>
383
+ </tr>
384
+ </table>
385
+
386
+ <h2><?php esc_html_e( 'Breakdown of search results', 'relevanssi' ); ?></h2>
387
+
388
+ <table id="relevanssi_breakdown" class="form-table
389
+ <?php
390
+ if ( empty( $excerpts ) ) {
391
+ echo 'relevanssi_disabled';
392
+ }
393
+ ?>
394
+ ">
395
+ <tr>
396
+ <th scope="row">
397
+ <label for='relevanssi_show_matches'><?php esc_html_e( 'Breakdown of search hits in excerpts', 'relevanssi' ); ?></label>
398
+ </th>
399
+ <td>
400
+ <fieldset>
401
+ <legend class="screen-reader-text"><?php esc_html_e( 'Show the breakdown of search hits in the excerpts', 'relevanssi' ); ?></legend>
402
+ <label for='relevanssi_show_matches'>
403
+ <input type='checkbox' name='relevanssi_show_matches' id='relevanssi_show_matches' <?php echo esc_html( $show_matches ); ?>
404
+ <?php
405
+ if ( empty( $excerpts ) ) {
406
+ echo "disabled='disabled'";
407
+ }
408
+ ?>
409
+ />
410
+ <?php esc_html_e( 'Show the breakdown of search hits in the excerpts.', 'relevanssi' ); ?>
411
+ </label>
412
+ </fieldset>
413
+ <p class="description"><?php esc_html_e( 'Requires custom snippets to work.', 'relevanssi' ); ?></p>
414
+ </td>
415
+ </tr>
416
+ <tr>
417
+ <th scope="row">
418
+ <label for='relevanssi_show_matches_text'><?php esc_html_e( 'The breakdown format', 'relevanssi' ); ?></label>
419
+ </th>
420
+ <td>
421
+ <textarea name='relevanssi_show_matches_text' id='relevanssi_show_matches_text' cols="80" rows="4"
422
+ <?php
423
+ if ( empty( $excerpts ) ) {
424
+ echo "disabled='disabled'";
425
+ }
426
+ ?>
427
+ ><?php echo esc_attr( $show_matches_text ); ?></textarea>
428
+ <p class="description"><?php esc_html_e( 'Use %body%, %title%, %tags% and %comments% to display the number of hits (in different parts of the post), %total% for total hits, %score% to display the document weight and %terms% to show how many hits each search term got.', 'relevanssi' ); /* phpcs:ignore WordPress.WP.I18n */ ?></p>
429
+ </td>
430
+ </tr>
431
+ </table>
432
+
433
+
434
+ <?php
435
+ }
lib/tabs/overview-tab.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * /lib/tabs/overview-tab.php
4
+ *
5
+ * Prints out the Overview tab in Relevanssi settings.
6
+ *
7
+ * @package Relevanssi
8
+ * @author Mikko Saari
9
+ * @license https://wordpress.org/about/gpl/ GNU General Public License
10
+ * @see https://www.relevanssi.com/
11
+ */
12
+
13
+ /**
14
+ * Prints out the overview tab in Relevanssi settings.
15
+ *
16
+ * @global array $relevanssi_variables The global Relevanssi variables array.
17
+ */
18
+ function relevanssi_overview_tab() {
19
+ global $relevanssi_variables;
20
+ $this_page = '?page=' . plugin_basename( $relevanssi_variables['file'] );
21
+ ?>
22
+ <h2><?php esc_html_e( 'Welcome to Relevanssi!', 'relevanssi' ); ?></h2>
23
+
24
+ <table class="form-table">
25
+
26
+ <?php
27
+ if ( ! is_multisite() && function_exists( 'relevanssi_form_api_key' ) ) {
28
+ relevanssi_form_api_key();
29
+ }
30
+ if ( function_exists( 'relevanssi_form_hide_post_controls' ) ) {
31
+ relevanssi_form_hide_post_controls();
32
+ }
33
+ ?>
34
+ <tr>
35
+ <th scope="row"><?php esc_html_e( 'Getting started', 'relevanssi' ); ?></th>
36
+ <td>
37
+ <p><?php esc_html_e( "You've already installed Relevanssi. That's a great first step towards good search experience!", 'relevanssi' ); ?></p>
38
+ <ol>
39
+ <?php if ( 'done' !== get_option( 'relevanssi_indexed' ) ) : ?>
40
+ <?php // Translators: %1$s opens the link, %2$s is the anchor text, %3$s closes the link. ?>
41
+ <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>
42
+ <p><?php esc_html_e( 'You need to check at least the following options:', 'relevanssi' ); ?><br />
43
+ – <?php esc_html_e( 'Make sure the post types you want to include in the index are indexed.', 'relevanssi' ); ?><br />
44
+ <?php // Translators: %s is '_sku'. ?>
45
+ – <?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>
46
+ <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>
47
+ </li>
48
+ <?php else : ?>
49
+ <li><p><?php esc_html_e( 'Great, you already have an index!', 'relevanssi' ); ?></p></li>
50
+ <?php endif; ?>
51
+ <li>
52
+ <?php // Translators: %1$s opens the link, %2$s is the anchor text, %3$s closes the link. ?>
53
+ <p><?php printf( esc_html__( 'On the %1$s%2$s%3$s tab, choose whether you want the default operator to be AND (less results, but more precise) or OR (more results, less precise).', 'relevanssi' ), "<a href='" . esc_attr( $this_page ) . "&amp;tab=searching'>", esc_html__( 'Searching', 'relevanssi' ), '</a>' ); ?></p>
54
+ </li>
55
+ <li>
56
+ <?php // Translators: %1$s opens the link, %2$s is the anchor text, %3$s closes the link. ?>
57
+ <p><?php printf( esc_html__( 'The next step is the %1$s%2$s%3$s tab, where you can enable the custom excerpts that show the relevant part of post in the search results pages.', 'relevanssi' ), "<a href='" . esc_attr( $this_page ) . "&amp;tab=excerpts'>", esc_html__( 'Excerpts and highlights', 'relevanssi' ), '</a>' ); ?></p>
58
+ <p><?php esc_html_e( 'There are couple of options related to that, so if you want highlighting in the results, you can adjust the styles for that to suit the look of your site.', 'relevanssi' ); ?></p>
59
+ </li>
60
+ <li>
61
+ <p><?php esc_html_e( "That's about it! Now you should have Relevanssi up and running. The rest of the options is mostly fine-tuning.", 'relevanssi' ); ?></p>
62
+ </li>
63
+ </ol>
64
+ <p><?php esc_html_e( "Relevanssi doesn't have a separate search widget. Instead, Relevanssi uses the default search widget. Any standard search form will do!", 'relevanssi' ); ?></p>
65
+ </td>
66
+ </tr>
67
+ <tr>
68
+ <th scope="row"><?php esc_html_e( 'For more information', 'relevanssi' ); ?></th>
69
+ <td>
70
+ <p><?php esc_html_e( "Relevanssi uses the WordPress contextual help. Click 'Help' on the top right corner for more information on many Relevanssi topics.", 'relevanssi' ); ?></p>
71
+ <?php // Translators: %1$s opens the link, %2$s closes the link. ?>
72
+ <p><?php printf( esc_html__( '%1$sRelevanssi knowledge base%2$s has lots of information about advanced Relevanssi use, including plenty of code samples.', 'relevanssi' ), "<a href='https://www.relevanssi.com/knowledge-base/'>", '</a>' ); ?></p>
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <th scope="row">
77
+ <?php esc_html_e( 'Relevanssi on Facebook', 'relevanssi' ); ?>
78
+ </th>
79
+ <td>
80
+ <p><a href="https://www.facebook.com/relevanssi"><?php esc_html_e( 'Check out the Relevanssi page on Facebook for news and updates about Relevanssi.', 'relevanssi' ); ?></a></p>
81
+ </td>
82
+ </tr>
83
+ <?php if ( ! RELEVANSSI_PREMIUM ) { ?>
84
+ <tr>
85
+ <th scope="row">
86
+ <?php esc_html_e( 'Buy Relevanssi Premium', 'relevanssi' ); ?>
87
+ </th>
88
+ <td>
89
+ <p><a href="https://www.relevanssi.com/buy-premium"><?php esc_html_e( 'Buy Relevanssi Premium now', 'relevanssi' ); ?></a> –
90
+ <?php // Translators: %1$s is the coupon code, %2$s is the year it expires. ?>
91
+ <?php printf( esc_html__( 'use coupon code %1$s for 20%% discount (valid at least until the end of %2$s)', 'relevanssi' ), '<strong>FREE2018</strong>', '2018' ); ?></p>
92
+ <p><?php esc_html_e( 'Here are some improvements Relevanssi Premium offers:', 'relevanssi' ); ?></p>
93
+ <ul class="relevanssi_ul">
94
+ <li><?php esc_html_e( 'PDF content indexing', 'relevanssi' ); ?></li>
95
+ <li><?php esc_html_e( 'Index and search user profile pages', 'relevanssi' ); ?></li>
96
+ <li><?php esc_html_e( 'Index and search taxonomy term pages', 'relevanssi' ); ?></li>
97
+ <li><?php esc_html_e( 'Multisite searches across many subsites', 'relevanssi' ); ?></li>
98
+ <li><?php esc_html_e( 'WP CLI commands', 'relevanssi' ); ?></li>
99
+ <li><?php esc_html_e( 'Adjust weights separately for each post type and taxonomy', 'relevanssi' ); ?></li>
100
+ <li><?php esc_html_e( 'Internal link anchors can be search terms for the target posts', 'relevanssi' ); ?></li>
101
+ <li><?php esc_html_e( 'Index and search any columns in the wp_posts database', 'relevanssi' ); ?></li>
102
+ <li><?php esc_html_e( 'Hide Relevanssi branding from the User Searches page on a client installation', 'relevanssi' ); ?></li>
103
+ </ul>
104
+ </td>
105
+ </tr>
106
+ <?php } // End if ( ! RELEVANSSI_PREMIUM ). ?>
107
+ </table>
108
+ <?php
109
+ }
lib/tabs/stopwords-tab.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * /lib/tabs/stopwords-tab.php
4
+ *
5
+ * Prints out the Stopwords tab in Relevanssi settings.
6
+ *
7
+ * @package Relevanssi
8
+ * @author Mikko Saari
9
+ * @license https://wordpress.org/about/gpl/ GNU General Public License
10
+ * @see https://www.relevanssi.com/
11
+ */
12
+
13
+ /**
14
+ * Prints out the stopwords tab in Relevanssi settings.
15
+ */
16
+ function relevanssi_stopwords_tab() {
17
+ ?>
18
+ <h3 id="stopwords"><?php esc_html_e( 'Stopwords', 'relevanssi' ); ?></h3>
19
+ <?php
20
+
21
+ relevanssi_show_stopwords();
22
+
23
+ /**
24
+ * Filters whether the common words list is displayed or not.
25
+ *
26
+ * The list of 25 most common words is displayed by default, but if the index is
27
+ * big, displaying the list can take a long time. This filter can be used to
28
+ * turn the list off.
29
+ *
30
+ * @param boolean If true, show the list; if false, don't show it.
31
+ */
32
+ if ( apply_filters( 'relevanssi_display_common_words', true ) ) {
33
+ relevanssi_common_words( 25 );
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Displays a list of stopwords.
39
+ *
40
+ * Displays the list of stopwords and gives the controls for adding new stopwords.
41
+ *
42
+ * @global object $wpdb The WP database interface.
43
+ * @global array $relevanssi_variables The global Relevanssi variables array.
44
+ */
45
+ function relevanssi_show_stopwords() {
46
+ global $wpdb, $relevanssi_variables;
47
+
48
+ $plugin = 'relevanssi';
49
+ if ( RELEVANSSI_PREMIUM ) {
50
+ $plugin = 'relevanssi-premium';
51
+ }
52
+
53
+ 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' ) );
54
+ ?>
55
+ <table class="form-table">
56
+ <tr>
57
+ <th scope="row">
58
+ <label for="addstopword"><p><?php esc_html_e( 'Stopword(s) to add', 'relevanssi' ); ?>
59
+ </th>
60
+ <td>
61
+ <textarea name="addstopword" id="addstopword" rows="2" cols="80"></textarea>
62
+ <p><input type="submit" value="<?php esc_attr_e( 'Add', 'relevanssi' ); ?>" class='button' /></p>
63
+ </td>
64
+ </tr>
65
+ </table>
66
+ <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>
67
+
68
+ <table class="form-table">
69
+ <tr>
70
+ <th scope="row">
71
+ <?php esc_html_e( 'Current stopwords', 'relevanssi' ); ?>
72
+ </th>
73
+ <td>
74
+ <?php
75
+ echo '<ul>';
76
+ $results = $wpdb->get_results( 'SELECT * FROM ' . $relevanssi_variables['stopword_table'] ); // WPCS: unprepared SQL ok, Relevanssi table name.
77
+ $exportlist = array();
78
+ foreach ( $results as $stopword ) {
79
+ $sw = stripslashes( $stopword->stopword );
80
+ printf( '<li style="display: inline;"><input type="submit" name="removestopword" value="%s"/></li>', esc_attr( $sw ) );
81
+ array_push( $exportlist, $sw );
82
+ }
83
+ echo '</ul>';
84
+
85
+ $exportlist = htmlspecialchars( implode( ', ', $exportlist ) );
86
+ ?>
87
+ <p><input type="submit" id="removeallstopwords" name="removeallstopwords" value="<?php esc_attr_e( 'Remove all stopwords', 'relevanssi' ); ?>" class='button' /></p>
88
+ </td>
89
+ </tr>
90
+ <tr>
91
+ <th scope="row">
92
+ <?php esc_html_e( 'Exportable list of stopwords', 'relevanssi' ); ?>
93
+ </th>
94
+ <td>
95
+ <textarea name="stopwords" id="stopwords" rows="2" cols="80"><?php echo esc_textarea( $exportlist ); ?></textarea>
96
+ <p class="description"><?php esc_html_e( 'You can copy the list of stopwords here if you want to back up the list, copy it to a different blog or otherwise need the list.', 'relevanssi' ); ?></p>
97
+ </td>
98
+ </tr>
99
+ </table>
100
+
101
+ <?php
102
+ }
103
+
104
+ /**
105
+ * Displays the list of most common words in the index.
106
+ *
107
+ * @global object $wpdb The WP database interface.
108
+ * @global array $relevanssi_variables The global Relevanssi variables.
109
+ *
110
+ * @param int $limit How many words to display, default 25.
111
+ * @param boolean $wp_cli If true, return just a list of words. If false, print out
112
+ * HTML code.
113
+ *
114
+ * @return array A list of words, if $wp_cli is true.
115
+ */
116
+ function relevanssi_common_words( $limit = 25, $wp_cli = false ) {
117
+ global $wpdb, $relevanssi_variables;
118
+
119
+ $plugin = 'relevanssi';
120
+ if ( RELEVANSSI_PREMIUM ) {
121
+ $plugin = 'relevanssi-premium';
122
+ }
123
+
124
+ if ( ! is_numeric( $limit ) ) {
125
+ $limit = 25;
126
+ }
127
+
128
+ $words = $wpdb->get_results( 'SELECT COUNT(*) as cnt, term FROM ' . $relevanssi_variables['relevanssi_table'] . " GROUP BY term ORDER BY cnt DESC LIMIT $limit" ); // WPCS: unprepared sql ok, Relevanssi table name and $limit is numeric.
129
+
130
+ if ( ! $wp_cli ) {
131
+ printf( '<h2>%s</h2>', esc_html__( '25 most common words in the index', 'relevanssi' ) );
132
+ printf( '<p>%s</p>', esc_html__( "These words are excellent stopword material. A word that appears in most of the posts in the database is quite pointless when searching. This is also an easy way to create a completely new stopword list, if one isn't available in your language. Click the icon after the word to add the word to the stopword list. The word will also be removed from the index, so rebuilding the index is not necessary.", 'relevanssi' ) );
133
+
134
+ ?>
135
+ <input type="hidden" name="dowhat" value="add_stopword" />
136
+ <table class="form-table">
137
+ <tr>
138
+ <th scope="row"><?php esc_html_e( 'Stopword Candidates', 'relevanssi' ); ?></th>
139
+ <td>
140
+ <ul>
141
+ <?php
142
+ $src = plugins_url( 'delete.png', $relevanssi_variables['file'] );
143
+
144
+ foreach ( $words as $word ) {
145
+ $stop = __( 'Add to stopwords', 'relevanssi' );
146
+ printf( '<li>%1$s (%2$d) <input style="padding: 0; margin: 0" type="image" src="%3$s" alt="%4$s" name="term" value="%5$s"/></li>', esc_html( $word->term ), esc_html( $word->cnt ), esc_attr( $src ), esc_attr( $stop ), esc_attr( $word->term ) );
147
+ }
148
+ ?>
149
+ </ul>
150
+ </td>
151
+ </tr>
152
+ </table>
153
+ <?php
154
+
155
+ }
156
+
157
+ return $words;
158
+ }
lib/tabs/synonyms-tab.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * /lib/tabs/synonyms-tab.php
4
+ *
5
+ * Prints out the Synonyms tab in Relevanssi settings.
6
+ *
7
+ * @package Relevanssi
8
+ * @author Mikko Saari
9
+ * @license https://wordpress.org/about/gpl/ GNU General Public License
10
+ * @see https://www.relevanssi.com/
11
+ */
12
+
13
+ /**
14
+ * Prints out the synonyms tab in Relevanssi settings.
15
+ */
16
+ function relevanssi_synonyms_tab() {
17
+ $synonyms = get_option( 'relevanssi_synonyms' );
18
+
19
+ if ( isset( $synonyms ) ) {
20
+ $synonyms = str_replace( ';', "\n", $synonyms );
21
+ } else {
22
+ $synonyms = '';
23
+ }
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
+ <?php esc_html_e( 'Synonyms', 'relevanssi' ); ?>
31
+ </th>
32
+ <td>
33
+ <p class="description"><?php esc_html_e( 'Add synonyms here to make the searches find better results. If you notice your users frequently misspelling a product name, or for other reasons use many names for one thing, adding synonyms will make the results better.', 'relevanssi' ); ?></p>
34
+
35
+ <p class="description"><?php esc_html_e( "Do not go overboard, though, as too many synonyms can make the search confusing: users understand if a search query doesn't match everything, but they get confused if the searches match to unexpected things.", 'relevanssi' ); ?></p>
36
+ <br />
37
+ <textarea name='relevanssi_synonyms' id='relevanssi_synonyms' rows='9' cols='60'><?php echo esc_textarea( htmlspecialchars( $synonyms ) ); ?></textarea>
38
+
39
+ <p class="description"><?php _e( 'The format here is <code>key = value</code>. If you add <code>dog = hound</code> to the list of synonyms, searches for <code>dog</code> automatically become a search for <code>dog hound</code> and will thus match to posts that include either <code>dog</code> or <code>hound</code>. This only works in OR searches: in AND searches the synonyms only restrict the search, as now the search only finds posts that contain <strong>both</strong> <code>dog</code> and <code>hound</code>.', 'relevanssi' ); // WPCS: XSS ok. ?></p>
40
+
41
+ <p class="description"><?php _e( 'The synonyms are one direction only. If you want both directions, add the synonym again, reversed: <code>hound = dog</code>.', 'relevanssi' ); // WPCS: XSS ok. ?></p>
42
+
43
+ <p class="description"><?php _e( "It's possible to use phrases for the value, but not for the key. <code>dog = \"great dane\"</code> works, but <code>\"great dane\" = dog</code> doesn't.", 'relevanssi' ); // WPCS: XSS ok. ?></p>
44
+
45
+ <?php if ( RELEVANSSI_PREMIUM ) : ?>
46
+ <p class="description"><?php esc_html_e( 'If you want to use synonyms in AND searches, enable synonym indexing on the Indexing tab.', 'relevanssi' ); ?></p>
47
+ <?php endif; ?>
48
+ </td>
49
+ </tr>
50
+ </table>
51
+ <?php
52
+ }
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: search, relevance, better search
5
  Requires at least: 4.0
6
  Tested up to: 5.0
7
  Requires PHP: 5.6
8
- Stable tag: 4.0.8
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -130,6 +130,15 @@ Each document database is full of useless words. All the little words that appea
130
 
131
  == Changelog ==
132
 
 
 
 
 
 
 
 
 
 
133
  = 4.0.8 =
134
  * Fixed cases where Relevanssi added an ellipsis even if the excerpt was from the start of the post.
135
  * Highlighting now works with numeric search strings.
@@ -161,6 +170,9 @@ Each document database is full of useless words. All the little words that appea
161
 
162
  == Upgrade notice ==
163
 
 
 
 
164
  = 4.0.8 =
165
  * Improvements to highlighting and excerpts.
166
 
5
  Requires at least: 4.0
6
  Tested up to: 5.0
7
  Requires PHP: 5.6
8
+ Stable tag: 4.0.9
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
130
 
131
  == Changelog ==
132
 
133
+ = 4.0.9 =
134
+ * Fixes broken tag and category indexing and searching. If you use tags and categories, rebuild the index after updating.
135
+ * Fixes phrase highlighting in documents.
136
+ * New filter: `relevanssi_indexing_restriction` allows filtering posts before indexing.
137
+ * New WooCommerce product visibility filtering tool makes WooCommerce product indexing faster.
138
+ * MemberPress post controls were loose and showed drafts to searchers. That is now fixed.
139
+ * Highlighting was too loose, even if matching was set to whole words.
140
+ * Highlighting now works better in cases where there's a hyphen or an apostrophe inside a word.
141
+
142
  = 4.0.8 =
143
  * Fixed cases where Relevanssi added an ellipsis even if the excerpt was from the start of the post.
144
  * Highlighting now works with numeric search strings.
170
 
171
  == Upgrade notice ==
172
 
173
+ = 4.0.9 =
174
+ * Fixes broken tag and category searching and indexing. Reindex after the update!
175
+
176
  = 4.0.8 =
177
  * Improvements to highlighting and excerpts.
178
 
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.0.8
17
  * Author: Mikko Saari
18
  * Author URI: http://www.mikkosaari.fi/
19
  * Text Domain: relevanssi
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.0.9
17
  * Author: Mikko Saari
18
  * Author URI: http://www.mikkosaari.fi/
19
  * Text Domain: relevanssi