Relevanssi – A Better Search - Version 4.1.1.1

Version Description

  • Adding the missing Gutenberg compatibility file.
Download this release

Release Info

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

Code changes from version 4.1.0.1 to 4.1.1.1

lib/admin-ajax.php CHANGED
@@ -270,7 +270,7 @@ function relevanssi_admin_search_debugging_info( $query ) {
270
  $result .= '<ul style="list-style: disc; margin-left: 1.5em">';
271
  foreach ( $query->query_vars as $key => $value ) {
272
  if ( is_array( $value ) ) {
273
- $value = implode( ', ', $value );
274
  }
275
  if ( empty( $value ) ) {
276
  continue;
@@ -282,7 +282,7 @@ function relevanssi_admin_search_debugging_info( $query ) {
282
  foreach ( $query->tax_query as $tax_query ) {
283
  foreach ( $tax_query as $key => $value ) {
284
  if ( is_array( $value ) ) {
285
- $value = implode( ', ', $value );
286
  }
287
  $result .= "<li>$key: $value</li>";
288
  }
270
  $result .= '<ul style="list-style: disc; margin-left: 1.5em">';
271
  foreach ( $query->query_vars as $key => $value ) {
272
  if ( is_array( $value ) ) {
273
+ $value = relevanssi_flatten_array( $value );
274
  }
275
  if ( empty( $value ) ) {
276
  continue;
282
  foreach ( $query->tax_query as $tax_query ) {
283
  foreach ( $tax_query as $key => $value ) {
284
  if ( is_array( $value ) ) {
285
+ $value = relevanssi_flatten_array( $value );
286
  }
287
  $result .= "<li>$key: $value</li>";
288
  }
lib/common.php CHANGED
@@ -647,6 +647,7 @@ function relevanssi_prevent_default_request( $request, $query ) {
647
  }
648
 
649
  $admin_search_ok = true;
 
650
  /**
651
  * Filters the admin search.
652
  *
@@ -1384,7 +1385,21 @@ function relevanssi_simple_didyoumean( $query, $pre, $post, $n = 5 ) {
1384
  function relevanssi_simple_generate_suggestion( $query ) {
1385
  global $wpdb, $relevanssi_variables;
1386
 
1387
- $q = 'SELECT query, count(query) as c, AVG(hits) as a FROM ' . $relevanssi_variables['log_table'] . ' WHERE hits > 1 GROUP BY query ORDER BY count(query) DESC';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1388
  $q = apply_filters( 'relevanssi_didyoumean_query', $q );
1389
 
1390
  $data = wp_cache_get( 'relevanssi_didyoumean_query' );
647
  }
648
 
649
  $admin_search_ok = true;
650
+
651
  /**
652
  * Filters the admin search.
653
  *
1385
  function relevanssi_simple_generate_suggestion( $query ) {
1386
  global $wpdb, $relevanssi_variables;
1387
 
1388
+ /**
1389
+ * The minimum limit of occurrances to include a word.
1390
+ *
1391
+ * To save resources, only words with more than this many occurrances are fed for
1392
+ * the spelling corrector. If there are problems with the spelling corrector,
1393
+ * increasing this value may fix those problems.
1394
+ *
1395
+ * @param int $number The number of occurrances must be more than this value,
1396
+ * default 2.
1397
+ */
1398
+ $count = apply_filters( 'relevanssi_get_words_having', 2 );
1399
+ if ( ! is_numeric( $count ) ) {
1400
+ $count = 2;
1401
+ }
1402
+ $q = 'SELECT query, count(query) as c, AVG(hits) as a FROM ' . $relevanssi_variables['log_table'] . ' WHERE hits > ' . $count . ' GROUP BY query ORDER BY count(query) DESC';
1403
  $q = apply_filters( 'relevanssi_didyoumean_query', $q );
1404
 
1405
  $data = wp_cache_get( 'relevanssi_didyoumean_query' );
lib/compatibility/gutenberg.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * /lib/compatibility/gutenberg.php
4
+ *
5
+ * Gutenberg compatibility features.
6
+ *
7
+ * @package Relevanssi
8
+ * @author Mikko Saari
9
+ * @license https://wordpress.org/about/gpl/ GNU General Public License
10
+ * @see https://www.relevanssi.com/
11
+ */
12
+
13
+ add_filter( 'relevanssi_post_content', 'relevanssi_gutenberg_block_rendering', 10, 2 );
14
+
15
+ /**
16
+ * Renders Gutenberg reusable blocks.
17
+ *
18
+ * Gutenberg Reusable Blocks appear as comments in the post content. This function
19
+ * picks up the comments and renders the blocks.
20
+ *
21
+ * @param string $content The post content.
22
+ * @param object $post The post object.
23
+ *
24
+ * @return string The post content with the rendered content added.
25
+ */
26
+ function relevanssi_gutenberg_block_rendering( $content, $post ) {
27
+ $blocks = gutenberg_parse_blocks( $post->post_content );
28
+
29
+ foreach ( $blocks as $block ) {
30
+ $attributes = (array) $block['attrs'];
31
+ $render = render_block_core_block( $attributes );
32
+ $content .= $render;
33
+ }
34
+ return $content;
35
+ }
lib/indexing.php CHANGED
@@ -786,7 +786,6 @@ function relevanssi_index_doc( $index_post, $remove_first = false, $custom_field
786
  if ( $debug ) {
787
  relevanssi_debug_echo( "\tPost content after relevanssi_post_content:\n$contents" );
788
  }
789
-
790
  /**
791
  * Can be used to add extra content to the post before indexing.
792
  *
@@ -799,7 +798,7 @@ function relevanssi_index_doc( $index_post, $remove_first = false, $custom_field
799
  if ( ! empty( $additional_content ) ) {
800
  $contents .= ' ' . $additional_content;
801
  if ( $debug ) {
802
- relevanssi_debug_echo( "\tAdditional content from relevanssi_content_to_index:\n$contents" );
803
  }
804
  }
805
 
786
  if ( $debug ) {
787
  relevanssi_debug_echo( "\tPost content after relevanssi_post_content:\n$contents" );
788
  }
 
789
  /**
790
  * Can be used to add extra content to the post before indexing.
791
  *
798
  if ( ! empty( $additional_content ) ) {
799
  $contents .= ' ' . $additional_content;
800
  if ( $debug ) {
801
+ relevanssi_debug_echo( "\tAdditional content from relevanssi_content_to_index:\n$additional_content" );
802
  }
803
  }
804
 
lib/init.php CHANGED
@@ -139,6 +139,10 @@ function relevanssi_init() {
139
  if ( class_exists( 'Obenland_Wp_Search_Suggest', false ) ) {
140
  require_once 'compatibility/wp-search-suggest.php';
141
  }
 
 
 
 
142
  }
143
 
144
  /**
139
  if ( class_exists( 'Obenland_Wp_Search_Suggest', false ) ) {
140
  require_once 'compatibility/wp-search-suggest.php';
141
  }
142
+
143
+ if ( defined( 'GUTENBERG_VERSION' ) ) {
144
+ require_once 'compatibility/gutenberg.php';
145
+ }
146
  }
147
 
148
  /**
lib/interface.php CHANGED
@@ -518,6 +518,20 @@ function relevanssi_truncate_logs( $verbose = true ) {
518
  * Uses relevanssi_total_queries() and relevanssi_date_queries() to fetch the data.
519
  */
520
  function relevanssi_query_log() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
521
  /**
522
  * Adjusts the number of days to show the logs in User searches page.
523
  *
@@ -544,11 +558,17 @@ function relevanssi_query_log() {
544
  printf( '<p>%s</p>', esc_html( sprintf( __( 'Here you can see the %d most common user search queries, how many times those queries were made and how many results were found for those queries.', 'relevanssi' ), $limit ) ) );
545
 
546
  echo "<div style='width: 30%; float: left; margin-right: 2%; overflow: auto'>";
547
- relevanssi_date_queries( 1, __( 'Today and yesterday', 'relevanssi' ) );
 
 
 
 
 
548
  echo '</div>';
549
 
550
  echo "<div style='width: 30%; float: left; margin-right: 2%; overflow: auto'>";
551
- relevanssi_date_queries( 7, __( 'Last 7 days', 'relevanssi' ) );
 
552
  echo '</div>';
553
 
554
  echo "<div style='width: 30%; float: left; margin-right: 2%; overflow: auto'>";
@@ -905,8 +925,9 @@ function relevanssi_add_admin_scripts( $hook ) {
905
  'searching_nonce' => wp_create_nonce( 'relevanssi_admin_search_nonce' ),
906
  );
907
 
908
- wp_localize_script( 'relevanssi_admin_js', 'nonce', $nonce );
909
-
 
910
  }
911
 
912
  /**
518
  * Uses relevanssi_total_queries() and relevanssi_date_queries() to fetch the data.
519
  */
520
  function relevanssi_query_log() {
521
+ /**
522
+ * Adjusts the number of days to show the logs in User searches page.
523
+ *
524
+ * @param int Number of days, default 1.
525
+ */
526
+ $days1 = apply_filters( 'relevanssi_1day', 1 );
527
+
528
+ /**
529
+ * Adjusts the number of days to show the logs in User searches page.
530
+ *
531
+ * @param int Number of days, default 7.
532
+ */
533
+ $days7 = apply_filters( 'relevanssi_7days', 7 );
534
+
535
  /**
536
  * Adjusts the number of days to show the logs in User searches page.
537
  *
558
  printf( '<p>%s</p>', esc_html( sprintf( __( 'Here you can see the %d most common user search queries, how many times those queries were made and how many results were found for those queries.', 'relevanssi' ), $limit ) ) );
559
 
560
  echo "<div style='width: 30%; float: left; margin-right: 2%; overflow: auto'>";
561
+ if ( 1 === $days1 ) {
562
+ relevanssi_date_queries( $days1, __( 'Today and yesterday', 'relevanssi' ) );
563
+ } else {
564
+ // Translators: number of days to show.
565
+ relevanssi_date_queries( $days1, springf( __( 'Last %d days', 'relevanssi' ), $days1 ) );
566
+ }
567
  echo '</div>';
568
 
569
  echo "<div style='width: 30%; float: left; margin-right: 2%; overflow: auto'>";
570
+ // Translators: number of days to show.
571
+ relevanssi_date_queries( $days7, springf( __( 'Last %d days', 'relevanssi' ), $days7 ) );
572
  echo '</div>';
573
 
574
  echo "<div style='width: 30%; float: left; margin-right: 2%; overflow: auto'>";
925
  'searching_nonce' => wp_create_nonce( 'relevanssi_admin_search_nonce' ),
926
  );
927
 
928
+ if ( ! RELEVANSSI_PREMIUM ) {
929
+ wp_localize_script( 'relevanssi_admin_js', 'nonce', $nonce );
930
+ }
931
  }
932
 
933
  /**
lib/log.php CHANGED
@@ -247,7 +247,7 @@ function relevanssi_export_log() {
247
  $now = gmdate( 'D, d M Y H:i:s' );
248
  $filename = 'relevanssi_log.csv';
249
 
250
- header( '"Expires: Tue, 03 Jul 2001 06:00:00 GMT' );
251
  header( 'Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate' );
252
  header( "Last-Modified: {$now} GMT" );
253
  header( 'Content-Type: application/force-download' );
247
  $now = gmdate( 'D, d M Y H:i:s' );
248
  $filename = 'relevanssi_log.csv';
249
 
250
+ header( 'Expires: Tue, 03 Jul 2001 06:00:00 GMT' );
251
  header( 'Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate' );
252
  header( "Last-Modified: {$now} GMT" );
253
  header( 'Content-Type: application/force-download' );
lib/search.php CHANGED
@@ -137,6 +137,7 @@ function relevanssi_search( $args ) {
137
  $by_date = $filtered_args['by_date'];
138
  $admin_search = $filtered_args['admin_search'];
139
  $include_attachments = $filtered_args['include_attachments'];
 
140
 
141
  $hits = array();
142
  $query_restrictions = '';
@@ -1074,7 +1075,6 @@ function relevanssi_search( $args ) {
1074
  if ( empty( $orderby ) ) {
1075
  $orderby = $default_order;
1076
  }
1077
-
1078
  if ( is_array( $orderby ) ) {
1079
  /**
1080
  * Filters the 'orderby' value just before sorting.
@@ -1087,7 +1087,7 @@ function relevanssi_search( $args ) {
1087
  * @param string The 'orderby' parameter.
1088
  */
1089
  $orderby = apply_filters( 'relevanssi_orderby', $orderby );
1090
- relevanssi_object_sort( $hits, $orderby );
1091
  } else {
1092
  if ( empty( $order ) ) {
1093
  $order = 'desc';
@@ -1110,7 +1110,7 @@ function relevanssi_search( $args ) {
1110
 
1111
  if ( 'relevance' !== $orderby ) {
1112
  $orderby_array = array( $orderby => $order );
1113
- relevanssi_object_sort( $hits, $orderby_array );
1114
  }
1115
  }
1116
  $return = array(
@@ -1494,10 +1494,10 @@ function relevanssi_do_query( &$query ) {
1494
  if ( isset( $query->query_vars['page_id'] ) ) {
1495
  $post_query = array( 'in' => array( $query->query_vars['page_id'] ) );
1496
  }
1497
- if ( isset( $query->query_vars['post__in'] ) ) {
1498
  $post_query = array( 'in' => $query->query_vars['post__in'] );
1499
  }
1500
- if ( isset( $query->query_vars['post__not_in'] ) ) {
1501
  $post_query = array( 'not in' => $query->query_vars['post__not_in'] );
1502
  }
1503
 
@@ -1505,10 +1505,10 @@ function relevanssi_do_query( &$query ) {
1505
  if ( isset( $query->query_vars['post_parent'] ) ) {
1506
  $parent_query = array( 'parent in' => array( $query->query_vars['post_parent'] ) );
1507
  }
1508
- if ( is_array( $query->query_vars['post_parent__in'] ) && ! empty( $query->query_vars['post_parent__in'] ) ) {
1509
  $parent_query = array( 'parent in' => $query->query_vars['post_parent__in'] );
1510
  }
1511
- if ( is_array( $query->query_vars['post_parent__not_in'] ) && ! empty( $query->query_vars['post_parent__not_in'] ) ) {
1512
  $parent_query = array( 'parent not in' => $query->query_vars['post_parent__not_in'] );
1513
  }
1514
 
@@ -1688,6 +1688,7 @@ function relevanssi_do_query( &$query ) {
1688
  'by_date' => $by_date,
1689
  'admin_search' => $admin_search,
1690
  'include_attachments' => $include_attachments,
 
1691
  );
1692
 
1693
  $return = relevanssi_search( $search_params );
137
  $by_date = $filtered_args['by_date'];
138
  $admin_search = $filtered_args['admin_search'];
139
  $include_attachments = $filtered_args['include_attachments'];
140
+ $meta_query = $filtered_args['meta_query'];
141
 
142
  $hits = array();
143
  $query_restrictions = '';
1075
  if ( empty( $orderby ) ) {
1076
  $orderby = $default_order;
1077
  }
 
1078
  if ( is_array( $orderby ) ) {
1079
  /**
1080
  * Filters the 'orderby' value just before sorting.
1087
  * @param string The 'orderby' parameter.
1088
  */
1089
  $orderby = apply_filters( 'relevanssi_orderby', $orderby );
1090
+ relevanssi_object_sort( $hits, $orderby, $meta_query );
1091
  } else {
1092
  if ( empty( $order ) ) {
1093
  $order = 'desc';
1110
 
1111
  if ( 'relevance' !== $orderby ) {
1112
  $orderby_array = array( $orderby => $order );
1113
+ relevanssi_object_sort( $hits, $orderby_array, $meta_query );
1114
  }
1115
  }
1116
  $return = array(
1494
  if ( isset( $query->query_vars['page_id'] ) ) {
1495
  $post_query = array( 'in' => array( $query->query_vars['page_id'] ) );
1496
  }
1497
+ if ( isset( $query->query_vars['post__in'] ) && is_array( $query->query_vars['post__in'] ) && ! empty( $query->query_vars['post__in'] ) ) {
1498
  $post_query = array( 'in' => $query->query_vars['post__in'] );
1499
  }
1500
+ if ( isset( $query->query_vars['post_not__in'] ) && is_array( $query->query_vars['post__not_in'] ) && ! empty( $query->query_vars['post__not_in'] ) ) {
1501
  $post_query = array( 'not in' => $query->query_vars['post__not_in'] );
1502
  }
1503
 
1505
  if ( isset( $query->query_vars['post_parent'] ) ) {
1506
  $parent_query = array( 'parent in' => array( $query->query_vars['post_parent'] ) );
1507
  }
1508
+ if ( isset( $query->query_vars['post_parent__in'] ) && is_array( $query->query_vars['post_parent__in'] ) && ! empty( $query->query_vars['post_parent__in'] ) ) {
1509
  $parent_query = array( 'parent in' => $query->query_vars['post_parent__in'] );
1510
  }
1511
+ if ( isset( $query->query_vars['post_parent__not_in'] ) && is_array( $query->query_vars['post_parent__not_in'] ) && ! empty( $query->query_vars['post_parent__not_in'] ) ) {
1512
  $parent_query = array( 'parent not in' => $query->query_vars['post_parent__not_in'] );
1513
  }
1514
 
1688
  'by_date' => $by_date,
1689
  'admin_search' => $admin_search,
1690
  'include_attachments' => $include_attachments,
1691
+ 'meta_query' => $meta_query,
1692
  );
1693
 
1694
  $return = relevanssi_search( $search_params );
lib/sorting.php CHANGED
@@ -80,6 +80,21 @@ function relevanssi_get_next_key( &$orderby ) {
80
  $compare = 'date';
81
  }
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  if ( 'rand(' === substr( $key, 0, 5 ) ) {
84
  $parts = explode( '(', $key );
85
  $dir = intval( trim( str_replace( ')', '', $parts[1] ) ) );
@@ -111,7 +126,7 @@ function relevanssi_get_next_key( &$orderby ) {
111
  * Fetches the key values for the item pair. If random order is required, this
112
  * function will randomize the order.
113
  *
114
- * @global object $wp_query The global WP_Query object.
115
  *
116
  * @param string $key The key used.
117
  * @param object $item_1 The first post object to compare.
@@ -131,19 +146,24 @@ function relevanssi_get_compare_values( $key, $item_1, $item_2 ) {
131
  );
132
  return $keys;
133
  }
134
-
135
  $key1 = '';
136
  $key2 = '';
137
-
138
  if ( 'meta_value' === $key || 'meta_value_num' === $key ) {
139
  global $wp_query;
140
  // Get the name of the field from the global WP_Query.
141
  $key = $wp_query->query_vars['meta_key'];
142
- if ( ! isset( $key ) ) {
143
- // The key is not set.
144
- return array( '', '' );
 
 
 
 
 
 
 
 
145
  }
146
-
147
  $key1 = get_post_meta( $item_1->ID, $key, true );
148
  if ( empty( $key1 ) ) {
149
  /**
@@ -169,8 +189,12 @@ function relevanssi_get_compare_values( $key, $item_1, $item_2 ) {
169
  $key2 = apply_filters( 'relevanssi_missing_sort_key', $key2, $key );
170
  }
171
  } else {
 
172
  if ( isset( $item_1->$key ) ) {
173
  $key1 = relevanssi_strtolower( $item_1->$key );
 
 
 
174
  } else {
175
  /**
176
  * Documented in lib/common.php.
@@ -179,6 +203,9 @@ function relevanssi_get_compare_values( $key, $item_1, $item_2 ) {
179
  }
180
  if ( isset( $item_2->$key ) ) {
181
  $key2 = relevanssi_strtolower( $item_2->$key );
 
 
 
182
  } else {
183
  /**
184
  * Documented in lib/common.php.
@@ -187,6 +214,13 @@ function relevanssi_get_compare_values( $key, $item_1, $item_2 ) {
187
  }
188
  }
189
 
 
 
 
 
 
 
 
190
  $keys = array(
191
  'key1' => $key1,
192
  'key2' => $key2,
@@ -262,7 +296,6 @@ function relevanssi_cmp_function( $a, $b ) {
262
  $compare_values = relevanssi_get_compare_values( $relevanssi_keys[ $level ], $a, $b );
263
  $val = relevanssi_compare_values( $compare_values['key1'], $compare_values['key2'], $compare );
264
  }
265
-
266
  if ( 'desc' === $relevanssi_dirs[ $level ] ) {
267
  $val = $val * -1;
268
  }
@@ -277,19 +310,23 @@ function relevanssi_cmp_function( $a, $b ) {
277
  * originally written by Matthew Hood and published in the PHP manual comments.
278
  * The actual sorting is handled by relevanssi_cmp_function().
279
  *
280
- * @global array $relevanssi_keys An array of sorting keys by level.
281
- * @global array $relevanssi_dirs An array of sorting directions by level.
282
- * @global array $relevanssi_compares An array of comparison methods by level.
 
283
  *
284
- * @param array $data The posts to sort are in $data[0], used as a reference.
285
- * @param array $orderby The array of orderby rules with directions.
 
 
286
  */
287
- function relevanssi_object_sort( &$data, $orderby ) {
288
- global $relevanssi_keys, $relevanssi_dirs, $relevanssi_compares;
289
 
290
- $relevanssi_keys = array();
291
- $relevanssi_dirs = array();
292
- $relevanssi_compares = array();
 
293
 
294
  do {
295
  $values = relevanssi_get_next_key( $orderby );
@@ -299,7 +336,6 @@ function relevanssi_object_sort( &$data, $orderby ) {
299
  $relevanssi_compares[] = $values['compare'];
300
  }
301
  } while ( ! empty( $values['key'] ) );
302
-
303
  $primary_key = $relevanssi_keys[0];
304
 
305
  usort( $data, 'relevanssi_cmp_function' );
80
  $compare = 'date';
81
  }
82
 
83
+ /**
84
+ * Lets you choose the compare method for fields.
85
+ *
86
+ * @param string $compare The compare method, can be 'string', 'number' or
87
+ * 'date'.
88
+ * @param string $key The name of the custom field key.
89
+ *
90
+ * @return string The compare method.
91
+ */
92
+ $compare = apply_filters( 'relevanssi_sort_compare', $compare, $key );
93
+ if ( ! in_array( $compare, array( 'string', 'number', 'date' ), true ) ) {
94
+ // Not a valid value, fall back.
95
+ $compare = 'string';
96
+ }
97
+
98
  if ( 'rand(' === substr( $key, 0, 5 ) ) {
99
  $parts = explode( '(', $key );
100
  $dir = intval( trim( str_replace( ')', '', $parts[1] ) ) );
126
  * Fetches the key values for the item pair. If random order is required, this
127
  * function will randomize the order.
128
  *
129
+ * @global array $relevanssi_meta_query The meta query used for the sorting.
130
  *
131
  * @param string $key The key used.
132
  * @param object $item_1 The first post object to compare.
146
  );
147
  return $keys;
148
  }
 
149
  $key1 = '';
150
  $key2 = '';
 
151
  if ( 'meta_value' === $key || 'meta_value_num' === $key ) {
152
  global $wp_query;
153
  // Get the name of the field from the global WP_Query.
154
  $key = $wp_query->query_vars['meta_key'];
155
+ if ( empty( $key ) ) {
156
+ // If empty, try the Relevanssi meta_query.
157
+ global $relevanssi_meta_query;
158
+ if ( isset( $relevanssi_meta_query[0]['key'] ) ) {
159
+ // Take from index 0, because using 'meta_value' requires the use of
160
+ // 'meta_key', which means there'll be just one key.
161
+ $key = $relevanssi_meta_query[0]['key'];
162
+ } else {
163
+ // The key is not set.
164
+ return array( '', '' );
165
+ }
166
  }
 
167
  $key1 = get_post_meta( $item_1->ID, $key, true );
168
  if ( empty( $key1 ) ) {
169
  /**
189
  $key2 = apply_filters( 'relevanssi_missing_sort_key', $key2, $key );
190
  }
191
  } else {
192
+ global $relevanssi_meta_query;
193
  if ( isset( $item_1->$key ) ) {
194
  $key1 = relevanssi_strtolower( $item_1->$key );
195
+ } elseif ( isset( $relevanssi_meta_query[ $key ] ) ) {
196
+ // Named meta queries.
197
+ $key1 = get_post_meta( $item_1->ID, $relevanssi_meta_query[ $key ]['key'], true );
198
  } else {
199
  /**
200
  * Documented in lib/common.php.
203
  }
204
  if ( isset( $item_2->$key ) ) {
205
  $key2 = relevanssi_strtolower( $item_2->$key );
206
+ } elseif ( isset( $relevanssi_meta_query[ $key ] ) ) {
207
+ // Named meta queries.
208
+ $key2 = get_post_meta( $item_2->ID, $relevanssi_meta_query[ $key ]['key'], true );
209
  } else {
210
  /**
211
  * Documented in lib/common.php.
214
  }
215
  }
216
 
217
+ if ( is_array( $key1 ) ) {
218
+ $key1 = relevanssi_flatten_array( $key1 );
219
+ }
220
+ if ( is_array( $key2 ) ) {
221
+ $key2 = relevanssi_flatten_array( $key2 );
222
+ }
223
+
224
  $keys = array(
225
  'key1' => $key1,
226
  'key2' => $key2,
296
  $compare_values = relevanssi_get_compare_values( $relevanssi_keys[ $level ], $a, $b );
297
  $val = relevanssi_compare_values( $compare_values['key1'], $compare_values['key2'], $compare );
298
  }
 
299
  if ( 'desc' === $relevanssi_dirs[ $level ] ) {
300
  $val = $val * -1;
301
  }
310
  * originally written by Matthew Hood and published in the PHP manual comments.
311
  * The actual sorting is handled by relevanssi_cmp_function().
312
  *
313
+ * @global array $relevanssi_keys An array of sorting keys by level.
314
+ * @global array $relevanssi_dirs An array of sorting directions by level.
315
+ * @global array $relevanssi_compares An array of comparison methods by level.
316
+ * @global array $relevanssi_meta_query The meta query array.
317
  *
318
+ * @param array $data The posts to sort are in $data[0], used as a reference.
319
+ * @param array $orderby The array of orderby rules with directions.
320
+ * @param array $meta_query The meta query array, in case it's needed for meta
321
+ * query based sorting.
322
  */
323
+ function relevanssi_object_sort( &$data, $orderby, $meta_query ) {
324
+ global $relevanssi_keys, $relevanssi_dirs, $relevanssi_compares, $relevanssi_meta_query;
325
 
326
+ $relevanssi_keys = array();
327
+ $relevanssi_dirs = array();
328
+ $relevanssi_compares = array();
329
+ $relevanssi_meta_query = $meta_query; // Store in a global variable to avoid complicated parameter passing.
330
 
331
  do {
332
  $values = relevanssi_get_next_key( $orderby );
336
  $relevanssi_compares[] = $values['compare'];
337
  }
338
  } while ( ! empty( $values['key'] ) );
 
339
  $primary_key = $relevanssi_keys[0];
340
 
341
  usort( $data, 'relevanssi_cmp_function' );
lib/tabs/stopwords-tab.php CHANGED
@@ -129,7 +129,7 @@ function relevanssi_common_words( $limit = 25, $wp_cli = false ) {
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" />
@@ -143,7 +143,7 @@ function relevanssi_common_words( $limit = 25, $wp_cli = false ) {
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>
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 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" />
143
 
144
  foreach ( $words as $word ) {
145
  $stop = __( 'Add to stopwords', 'relevanssi' );
146
+ printf( '<li><input style="padding: 0; margin: 0" type="submit" src="%1$s" name="term" value="%2$s"/> (%3$d)</li>', esc_attr( $src ), esc_attr( $word->term ), esc_html( $word->cnt ) );
147
  }
148
  ?>
149
  </ul>
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.1.0.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -130,6 +130,18 @@ Each document database is full of useless words. All the little words that appea
130
 
131
  == Changelog ==
132
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  = 4.1.0.1 =
134
  * Actually working admin search.
135
 
@@ -175,6 +187,12 @@ Each document database is full of useless words. All the little words that appea
175
 
176
  == Upgrade notice ==
177
 
 
 
 
 
 
 
178
  = 4.1 =
179
  * New features and plenty of small fixes.
180
 
5
  Requires at least: 4.0
6
  Tested up to: 5.0
7
  Requires PHP: 5.6
8
+ Stable tag: 4.1.1.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
130
 
131
  == Changelog ==
132
 
133
+ = 4.1.1.1 =
134
+ * Adding the missing Gutenberg compatibility file.
135
+
136
+ = 4.1.1 =
137
+ * Relevanssi can now index Gutenberg reusable blocks. (This functionality broke once already before release, so that can happen, since Gutenberg is still in very active development.)
138
+ * The `post__in` and `post__not_in` parameters didn't work, and are now fixed. `post_parent__in` and `post_parent__not_in` are also improved.
139
+ * You can use named meta queries for sorting posts. Meta query sorting is improved in other ways as well.
140
+ * Log export didn't work properly.
141
+ * Adding stopwords from the common word list has been fixed.
142
+ * The `relevanssi_get_words_having` filter hook is now also applied to the free version Did you mean queries.
143
+ * New filters: `relevanssi_1day` and `relevanssi_7days` can be used to adjust the number of days for log displays, so instead of 1, 7 and 30 days you can have anything you want.
144
+
145
  = 4.1.0.1 =
146
  * Actually working admin search.
147
 
187
 
188
  == Upgrade notice ==
189
 
190
+ = 4.1.1.1 =
191
+ * Adding the missing Gutenberg compatibility file.
192
+
193
+ = 4.1.1 =
194
+ * Minor improvements here and there, particularly in custom field sorting.
195
+
196
  = 4.1 =
197
  * New features and plenty of small fixes.
198
 
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.1.0.1
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.1.1.1
17
  * Author: Mikko Saari
18
  * Author URI: http://www.mikkosaari.fi/
19
  * Text Domain: relevanssi