Relevanssi – A Better Search - Version 3.5.12

Version Description

  • Post type exclusion didn't work as expected.
  • Relevanssi couldn't handle nested tax queries (such as those generated by WooCommerce product visibility filtering) properly.
Download this release

Release Info

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

Code changes from version 3.5.11.1 to 3.5.12

Files changed (4) hide show
  1. lib/search.php +262 -188
  2. lib/uninstall.php +5 -5
  3. readme.txt +5 -4
  4. relevanssi.php +1 -1
lib/search.php CHANGED
@@ -87,195 +87,24 @@ function relevanssi_search($args) {
87
  $and_term_tax_ids = array();
88
 
89
  if (is_array($tax_query)) {
 
90
  foreach ($tax_query as $row) {
91
- $using_term_tax_id = false;
92
- if ($row['field'] == 'slug') {
93
- $slug = $row['terms'];
94
- $numeric_slugs = array();
95
- $slug_in = null;
96
- if (is_array($slug)) {
97
- $slugs = array();
98
- $term_id = array();
99
- foreach ($slug as $t_slug) {
100
- $term = get_term_by('slug', $t_slug, $row['taxonomy']);
101
- if (!$term && is_numeric($t_slug)) {
102
- $numeric_slugs[] = "'$t_slug'";
103
- }
104
- else {
105
- $t_slug = sanitize_title($t_slug);
106
- $term_id[] = $term->term_id;
107
- $slugs[] = "'$t_slug'";
108
- }
109
- }
110
- if (!empty($slugs)) $slug_in = implode(',', $slugs);
111
- }
112
- else {
113
- $term = get_term_by('slug', $slug, $row['taxonomy']);
114
- if (!$term && is_numeric($slug)) {
115
- $numeric_slugs[] = $slug;
116
- }
117
- else {
118
- $slug = sanitize_title($slug);
119
- $term_id = $term->term_id;
120
- $slug_in = "'$slug'";
121
- }
122
- }
123
- if (!empty($slug_in)) {
124
- $row_taxonomy = sanitize_text_field($row['taxonomy']);
125
- $tt_q = "SELECT tt.term_taxonomy_id
126
- FROM $wpdb->term_taxonomy AS tt
127
- LEFT JOIN $wpdb->terms AS t ON (tt.term_id=t.term_id)
128
- WHERE tt.taxonomy = '$row_taxonomy' AND t.slug IN ($slug_in)";
129
- // Clean: $row_taxonomy is sanitized, each slug in $slug_in is sanitized
130
- $term_tax_id = $wpdb->get_col($tt_q);
131
- }
132
- if (!empty($numeric_slugs)) $row['field'] = 'id';
133
- }
134
- if ($row['field'] == 'name') {
135
- $name = $row['terms'];
136
- $numeric_names = array();
137
- $name_in = null;
138
- if (is_array($name)) {
139
- $names = array();
140
- $term_id = array();
141
- foreach ($name as $t_name) {
142
- $term = get_term_by('name', $t_name, $row['taxonomy']);
143
- if (!$term && is_numeric($t_names)) {
144
- $numeric_names[] = "'$t_name'";
145
- }
146
- else {
147
- $t_name = sanitize_title($t_name);
148
- $term_id[] = $term->term_id;
149
- $names[] = "'$t_name'";
150
- }
151
- }
152
- if (!empty($names)) $name_in = implode(',', $names);
153
- }
154
- else {
155
- $term = get_term_by('name', $name, $row['taxonomy']);
156
- if (!$term && is_numeric($name)) {
157
- $numeric_slugs[] = $name;
158
- }
159
- else {
160
- if (isset($term->term_id)) {
161
- $name = sanitize_title($name);
162
- $term_id = $term->term_id;
163
- $name_in = "'$name'";
164
- }
165
- }
166
- }
167
- if (!empty($name_in)) {
168
- $row_taxonomy = sanitize_text_field($row['taxonomy']);
169
- $tt_q = "SELECT tt.term_taxonomy_id
170
- FROM $wpdb->term_taxonomy AS tt
171
- LEFT JOIN $wpdb->terms AS t ON (tt.term_id=t.term_id)
172
- WHERE tt.taxonomy = '$row_taxonomy' AND t.name IN ($name_in)";
173
- // Clean: $row_taxonomy is sanitized, each name in $name_in is sanitized
174
- $term_tax_id = $wpdb->get_col($tt_q);
175
- }
176
- if (!empty($numeric_names)) $row['field'] = 'id';
177
- }
178
- if ($row['field'] == 'id' || $row['field'] == 'term_id') {
179
- $id = $row['terms'];
180
- $term_id = $id;
181
- if (is_array($id)) {
182
- $numeric_values = array();
183
- foreach ($id as $t_id) {
184
- if (is_numeric($t_id)) $numeric_values[] = $t_id;
185
- }
186
- $id = implode(',', $numeric_values);
187
- }
188
- $row_taxonomy = sanitize_text_field($row['taxonomy']);
189
- $tt_q = "SELECT tt.term_taxonomy_id
190
- FROM $wpdb->term_taxonomy AS tt
191
- LEFT JOIN $wpdb->terms AS t ON (tt.term_id=t.term_id)
192
- WHERE tt.taxonomy = '$row_taxonomy' AND t.term_id IN ($id)";
193
- // Clean: $row_taxonomy is sanitized, $id is checked to be numeric
194
- $id_term_tax_id = $wpdb->get_col($tt_q);
195
- if (!empty($term_tax_id) && is_array($term_tax_id)) {
196
- $term_tax_id = array_unique(array_merge($term_tax_id, $id_term_tax_id));
197
- }
198
- else {
199
- $term_tax_id = $id_term_tax_id;
200
- }
201
  }
202
- if ($row['field'] == 'term_taxonomy_id') {
203
- $using_term_tax_id = true;
204
- $id = $row['terms'];
205
- $term_tax_id = $id;
206
- if (is_array($id)) {
207
- $numeric_values = array();
208
- foreach ($id as $t_id) {
209
- if (is_numeric($t_id)) $numeric_values[] = $t_id;
210
- }
211
- $term_tax_id = implode(',', $numeric_values);
212
- }
213
- }
214
-
215
- if (!isset($row['include_children']) || $row['include_children'] == true) {
216
- if (!$using_term_tax_id && isset($term_id)) {
217
- if (!is_array($term_id)) {
218
- $term_id = array($term_id);
219
- }
220
- }
221
- else {
222
- if (!is_array($term_tax_id)) {
223
- $term_tax_id = array($term_tax_id);
224
- $term_id = $term_tax_id;
225
- }
226
- }
227
- if (isset($term_id) && is_array($term_id)) {
228
- foreach ($term_id as $t_id) {
229
- if ($using_term_tax_id) {
230
- $t_term = get_term_by('term_taxonomy_id', $t_id, $row['taxonomy']);
231
- $t_id = $t_term->ID;
232
- }
233
- $kids = get_term_children($t_id, $row['taxonomy']);
234
- foreach ($kids as $kid) {
235
- $term = get_term_by('id', $kid, $row['taxonomy']);
236
- $term_tax_id[] = relevanssi_get_term_tax_id('id', $kid, $row['taxonomy']);
237
- }
238
- }
239
- }
240
- }
241
-
242
- $term_tax_id = array_unique($term_tax_id);
243
- if (!empty($term_tax_id)) {
244
- $n = count($term_tax_id);
245
- $term_tax_id = implode(',', $term_tax_id);
246
-
247
- $tq_operator = 'IN';
248
- if (isset($row['operator'])) $tq_operator = strtoupper($row['operator']);
249
- if ($tq_operator != 'IN' && $tq_operator != 'NOT IN' && $tq_operator != 'AND') $tq_operator = 'IN';
250
- if ($tax_query_relation == 'and') {
251
- if ($tq_operator == 'AND') {
252
- $query_restrictions .= " AND relevanssi.doc IN (
253
- SELECT ID FROM $wpdb->posts WHERE 1=1
254
- AND (
255
- SELECT COUNT(1)
256
- FROM $wpdb->term_relationships AS tr
257
- WHERE tr.term_taxonomy_id IN ($term_tax_id)
258
- AND tr.object_id = $wpdb->posts.ID ) = $n
259
- )";
260
- // Clean: $term_tax_id and $n are Relevanssi-generated
261
- }
262
- else {
263
- $query_restrictions .= " AND relevanssi.doc $tq_operator (SELECT DISTINCT(tr.object_id) FROM $wpdb->term_relationships AS tr
264
- WHERE tr.term_taxonomy_id IN ($term_tax_id))";
265
- // Clean: all variables are Relevanssi-generated
266
  }
267
  }
268
- else {
269
- if ($tq_operator == 'IN') $term_tax_ids[] = $term_tax_id;
270
- if ($tq_operator == 'NOT IN') $not_term_tax_ids[] = $term_tax_id;
271
- if ($tq_operator == 'AND') $and_term_tax_ids[] = $term_tax_id;
272
- }
273
- }
274
- else {
275
- global $wp_query;
276
- $wp_query->is_category = false;
277
  }
278
  }
 
279
  if ($tax_query_relation == 'or') {
280
  $term_tax_ids = array_unique($term_tax_ids);
281
  if (count($term_tax_ids) > 0) {
@@ -378,8 +207,8 @@ function relevanssi_search($args) {
378
  // If $post_type is set, there's no need to exclude, as we only include.
379
  !$post_type ? $negative_post_type = relevanssi_get_negative_post_type() : $negative_post_type = NULL;
380
 
381
- $non_post_post_types_array = array();
382
  $non_post_post_type = NULL;
 
383
  if (function_exists('relevanssi_get_non_post_post_types')) {
384
  $non_post_post_types_array = relevanssi_get_non_post_post_types();
385
  }
@@ -655,7 +484,7 @@ function relevanssi_search($args) {
655
  do {
656
  foreach ($terms as $term) {
657
  $term = trim($term); // numeric search terms will start with a space
658
- if (relevanssi_strlen($term) < 2) continue;
659
  $term = esc_sql($term);
660
 
661
  if (strpos($o_term_cond, 'LIKE') !== false) {
@@ -1452,11 +1281,11 @@ function relevanssi_get_negative_post_type() {
1452
 
1453
  // Post types to exclude.
1454
  if ($negative_post_type_list) {
1455
- if (!is_array($negative_post_type)) {
1456
- $negative_post_types = esc_sql(explode(',', $negative_post_type));
1457
  }
1458
  else {
1459
- $negative_post_types = esc_sql($negative_post_type);
1460
  }
1461
  $negative_post_type = count($negative_post_types) ? "'" . implode( "', '", $negative_post_types) . "'" : NULL;
1462
  }
@@ -1464,4 +1293,249 @@ function relevanssi_get_negative_post_type() {
1464
 
1465
  return $negative_post_type;
1466
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1467
  ?>
87
  $and_term_tax_ids = array();
88
 
89
  if (is_array($tax_query)) {
90
+ $is_sub_row = false;
91
  foreach ($tax_query as $row) {
92
+ if (isset($row['terms'])) {
93
+ list($query_restrictions, $term_tax_ids, $not_term_tax_ids, $and_term_tax_ids) = relevanssi_process_tax_query_row($row, $is_sub_row, $tax_query_relation, $query_restrictions, $tax_query_relation, $term_tax_ids, $not_term_tax_ids, $and_term_tax_ids);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
95
+ else {
96
+ $row_tax_query_relation = $tax_query_relation;
97
+ if (isset($row['relation'])) $row_tax_query_relation = strtolower($row['relation']);
98
+ foreach ($row as $subrow) {
99
+ $is_sub_row = true;
100
+ if (isset($subrow['terms'])) {
101
+ list($query_restrictions, $term_tax_ids, $not_term_tax_ids, $and_term_tax_ids) = relevanssi_process_tax_query_row($subrow, $is_sub_row, $tax_query_relation, $query_restrictions, $tax_query_relation, $term_tax_ids, $not_term_tax_ids, $and_term_tax_ids);
102
+ // For subrows, we only want the query_restrictions
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  }
104
  }
 
 
 
 
 
 
 
 
 
105
  }
106
  }
107
+
108
  if ($tax_query_relation == 'or') {
109
  $term_tax_ids = array_unique($term_tax_ids);
110
  if (count($term_tax_ids) > 0) {
207
  // If $post_type is set, there's no need to exclude, as we only include.
208
  !$post_type ? $negative_post_type = relevanssi_get_negative_post_type() : $negative_post_type = NULL;
209
 
 
210
  $non_post_post_type = NULL;
211
+ $non_post_post_types_array = array();
212
  if (function_exists('relevanssi_get_non_post_post_types')) {
213
  $non_post_post_types_array = relevanssi_get_non_post_post_types();
214
  }
484
  do {
485
  foreach ($terms as $term) {
486
  $term = trim($term); // numeric search terms will start with a space
487
+ if (apply_filters('relevanssi_block_one_letter_searches', relevanssi_strlen($term) < 2)) continue;
488
  $term = esc_sql($term);
489
 
490
  if (strpos($o_term_cond, 'LIKE') !== false) {
1281
 
1282
  // Post types to exclude.
1283
  if ($negative_post_type_list) {
1284
+ if (!is_array($negative_post_type_list)) {
1285
+ $negative_post_types = esc_sql(explode(',', $negative_post_type_list));
1286
  }
1287
  else {
1288
+ $negative_post_types = esc_sql($negative_post_type_list);
1289
  }
1290
  $negative_post_type = count($negative_post_types) ? "'" . implode( "', '", $negative_post_types) . "'" : NULL;
1291
  }
1293
 
1294
  return $negative_post_type;
1295
  }
1296
+
1297
+ function relevanssi_process_tax_query_row($row, $is_sub_row, $global_relation, $query_restrictions, $tax_query_relation, $term_tax_ids, $not_term_tax_ids, $and_term_tax_ids) {
1298
+ global $wpdb;
1299
+
1300
+ $local_term_tax_ids = array();
1301
+ $local_not_term_tax_ids = array();
1302
+ $local_and_term_tax_ids = array();
1303
+
1304
+ $using_term_tax_id = false;
1305
+ if (!isset($row['field'])) $row['field'] = 'term_id'; // in case 'field' is not set, go with the WP default of "term_id"
1306
+ if ($row['field'] == 'slug') {
1307
+ $slug = $row['terms'];
1308
+ $numeric_slugs = array();
1309
+ $slug_in = null;
1310
+ if (is_array($slug)) {
1311
+ $slugs = array();
1312
+ $term_id = array();
1313
+ foreach ($slug as $t_slug) {
1314
+ $term = get_term_by('slug', $t_slug, $row['taxonomy']);
1315
+ if (!$term && is_numeric($t_slug)) {
1316
+ $numeric_slugs[] = "'$t_slug'";
1317
+ }
1318
+ else {
1319
+ $t_slug = sanitize_title($t_slug);
1320
+ $term_id[] = $term->term_id;
1321
+ $slugs[] = "'$t_slug'";
1322
+ }
1323
+ }
1324
+ if (!empty($slugs)) $slug_in = implode(',', $slugs);
1325
+ }
1326
+ else {
1327
+ $term = get_term_by('slug', $slug, $row['taxonomy']);
1328
+ if (!$term && is_numeric($slug)) {
1329
+ $numeric_slugs[] = $slug;
1330
+ }
1331
+ else {
1332
+ $slug = sanitize_title($slug);
1333
+ $term_id = $term->term_id;
1334
+ $slug_in = "'$slug'";
1335
+ }
1336
+ }
1337
+ if (!empty($slug_in)) {
1338
+ $row_taxonomy = sanitize_text_field($row['taxonomy']);
1339
+ $tt_q = "SELECT tt.term_taxonomy_id
1340
+ FROM $wpdb->term_taxonomy AS tt
1341
+ LEFT JOIN $wpdb->terms AS t ON (tt.term_id=t.term_id)
1342
+ WHERE tt.taxonomy = '$row_taxonomy' AND t.slug IN ($slug_in)";
1343
+ // Clean: $row_taxonomy is sanitized, each slug in $slug_in is sanitized
1344
+ $term_tax_id = $wpdb->get_col($tt_q);
1345
+ }
1346
+ if (!empty($numeric_slugs)) $row['field'] = 'term_id';
1347
+ }
1348
+ if ($row['field'] == 'name') {
1349
+ $name = $row['terms'];
1350
+ $numeric_names = array();
1351
+ $name_in = null;
1352
+ if (is_array($name)) {
1353
+ $names = array();
1354
+ $term_id = array();
1355
+ foreach ($name as $t_name) {
1356
+ $term = get_term_by('name', $t_name, $row['taxonomy']);
1357
+ if (!$term && is_numeric($t_names)) {
1358
+ $numeric_names[] = "'$t_name'";
1359
+ }
1360
+ else {
1361
+ $t_name = sanitize_title($t_name);
1362
+ $term_id[] = $term->term_id;
1363
+ $names[] = "'$t_name'";
1364
+ }
1365
+ }
1366
+ if (!empty($names)) $name_in = implode(',', $names);
1367
+ }
1368
+ else {
1369
+ $term = get_term_by('name', $name, $row['taxonomy']);
1370
+ if (!$term && is_numeric($name)) {
1371
+ $numeric_slugs[] = $name;
1372
+ }
1373
+ else {
1374
+ if (isset($term->term_id)) {
1375
+ $name = sanitize_title($name);
1376
+ $term_id = $term->term_id;
1377
+ $name_in = "'$name'";
1378
+ }
1379
+ }
1380
+ }
1381
+ if (!empty($name_in)) {
1382
+ $row_taxonomy = sanitize_text_field($row['taxonomy']);
1383
+ $tt_q = "SELECT tt.term_taxonomy_id
1384
+ FROM $wpdb->term_taxonomy AS tt
1385
+ LEFT JOIN $wpdb->terms AS t ON (tt.term_id=t.term_id)
1386
+ WHERE tt.taxonomy = '$row_taxonomy' AND t.name IN ($name_in)";
1387
+ // Clean: $row_taxonomy is sanitized, each name in $name_in is sanitized
1388
+ $term_tax_id = $wpdb->get_col($tt_q);
1389
+ }
1390
+ if (!empty($numeric_names)) $row['field'] = 'term_id';
1391
+ }
1392
+ if ($row['field'] == 'id' || $row['field'] == 'term_id') {
1393
+ $id = $row['terms'];
1394
+ $term_id = $id;
1395
+ if (is_array($id)) {
1396
+ $numeric_values = array();
1397
+ foreach ($id as $t_id) {
1398
+ if (is_numeric($t_id)) $numeric_values[] = $t_id;
1399
+ }
1400
+ $id = implode(',', $numeric_values);
1401
+ }
1402
+ $row_taxonomy = sanitize_text_field($row['taxonomy']);
1403
+ $tt_q = "SELECT tt.term_taxonomy_id
1404
+ FROM $wpdb->term_taxonomy AS tt
1405
+ LEFT JOIN $wpdb->terms AS t ON (tt.term_id=t.term_id)
1406
+ WHERE tt.taxonomy = '$row_taxonomy' AND t.term_id IN ($id)";
1407
+ // Clean: $row_taxonomy is sanitized, $id is checked to be numeric
1408
+ $id_term_tax_id = $wpdb->get_col($tt_q);
1409
+ if (!empty($term_tax_id) && is_array($term_tax_id)) {
1410
+ $term_tax_id = array_unique(array_merge($term_tax_id, $id_term_tax_id));
1411
+ }
1412
+ else {
1413
+ $term_tax_id = $id_term_tax_id;
1414
+ }
1415
+ }
1416
+ if ($row['field'] == 'term_taxonomy_id') {
1417
+ $using_term_tax_id = true;
1418
+ $id = $row['terms'];
1419
+ $term_tax_id = $id;
1420
+ if (is_array($id)) {
1421
+ $numeric_values = array();
1422
+ foreach ($id as $t_id) {
1423
+ if (is_numeric($t_id)) $numeric_values[] = $t_id;
1424
+ }
1425
+ $term_tax_id = implode(',', $numeric_values);
1426
+ }
1427
+ }
1428
+
1429
+ if (!isset($row['include_children']) || $row['include_children'] == true) {
1430
+ if (!$using_term_tax_id && isset($term_id)) {
1431
+ if (!is_array($term_id)) {
1432
+ $term_id = array($term_id);
1433
+ }
1434
+ }
1435
+ else {
1436
+ if (!is_array($term_tax_id)) {
1437
+ $term_tax_id = array($term_tax_id);
1438
+ $term_id = $term_tax_id;
1439
+ }
1440
+ }
1441
+ if (empty($term_tax_id)) $term_tax_id = array();
1442
+ if (!is_array($term_tax_id)) $term_tax_id = array($term_tax_id);
1443
+ if (isset($term_id) && is_array($term_id)) {
1444
+ foreach ($term_id as $t_id) {
1445
+ if ($using_term_tax_id) {
1446
+ $t_term = get_term_by('term_taxonomy_id', $t_id, $row['taxonomy']);
1447
+ $t_id = $t_term->ID;
1448
+ }
1449
+ $kids = get_term_children($t_id, $row['taxonomy']);
1450
+ foreach ($kids as $kid) {
1451
+ $term = get_term_by('id', $kid, $row['taxonomy']);
1452
+ $kid_term_tax_id = relevanssi_get_term_tax_id('id', $kid, $row['taxonomy']);
1453
+ $term_tax_id[] = $kid_term_tax_id;
1454
+ }
1455
+ }
1456
+ }
1457
+ }
1458
+
1459
+ $term_tax_id = array_unique($term_tax_id);
1460
+ if (!empty($term_tax_id)) {
1461
+ $n = count($term_tax_id);
1462
+ $term_tax_id = implode(',', $term_tax_id);
1463
+
1464
+ $tq_operator = 'IN'; // Assuming the default operator "IN", unless something else is provided.
1465
+ if (isset($row['operator'])) $tq_operator = strtoupper($row['operator']);
1466
+ if ($tq_operator != 'IN' && $tq_operator != 'NOT IN' && $tq_operator != 'AND') $tq_operator = 'IN';
1467
+ if ($tax_query_relation == 'and') {
1468
+ if ($tq_operator == 'AND') {
1469
+ $query_restrictions .= " AND relevanssi.doc IN (
1470
+ SELECT ID FROM $wpdb->posts WHERE 1=1
1471
+ AND (
1472
+ SELECT COUNT(1)
1473
+ FROM $wpdb->term_relationships AS tr
1474
+ WHERE tr.term_taxonomy_id IN ($term_tax_id)
1475
+ AND tr.object_id = $wpdb->posts.ID ) = $n
1476
+ )";
1477
+ // Clean: $term_tax_id and $n are Relevanssi-generated
1478
+ }
1479
+ else {
1480
+ $query_restrictions .= " AND relevanssi.doc $tq_operator (SELECT DISTINCT(tr.object_id) FROM $wpdb->term_relationships AS tr
1481
+ WHERE tr.term_taxonomy_id IN ($term_tax_id))";
1482
+ // Clean: all variables are Relevanssi-generated
1483
+ }
1484
+ }
1485
+ else {
1486
+ if ($tq_operator == 'IN') $local_term_tax_ids[] = $term_tax_id;
1487
+ if ($tq_operator == 'NOT IN') $local_not_term_tax_ids[] = $term_tax_id;
1488
+ if ($tq_operator == 'AND') $local_and_term_tax_ids[] = $term_tax_id;
1489
+ }
1490
+ }
1491
+ else {
1492
+ global $wp_query;
1493
+ $wp_query->is_category = false;
1494
+ }
1495
+
1496
+ if ($is_sub_row && $global_relation == 'and' && $tax_query_relation == 'or') {
1497
+ $local_term_tax_ids = array_unique($local_term_tax_ids);
1498
+ $local_not_term_tax_ids = array_unique($local_not_term_tax_ids);
1499
+ $local_and_term_tax_ids = array_unique($local_and_term_tax_ids);
1500
+ if (count($local_term_tax_ids) > 0) {
1501
+ $local_term_tax_ids = implode(',', $local_term_tax_ids);
1502
+ $query_restrictions .= " AND relevanssi.doc IN (SELECT DISTINCT(tr.object_id) FROM $wpdb->term_relationships AS tr
1503
+ WHERE tr.term_taxonomy_id IN ($local_term_tax_ids))";
1504
+ // Clean: all variables are Relevanssi-generated
1505
+ }
1506
+ if (count($local_not_term_tax_ids) > 0) {
1507
+ $local_not_term_tax_ids = implode(',', $local_not_term_tax_ids);
1508
+ $query_restrictions .= " AND relevanssi.doc NOT IN (SELECT DISTINCT(tr.object_id) FROM $wpdb->term_relationships AS tr
1509
+ WHERE tr.term_taxonomy_id IN ($local_not_term_tax_ids))";
1510
+ // Clean: all variables are Relevanssi-generated
1511
+ }
1512
+ if (count($local_and_term_tax_ids) > 0) {
1513
+ $local_and_term_tax_ids = implode(',', $local_and_term_tax_ids);
1514
+ $n = count(explode(',', $local_and_term_tax_ids));
1515
+ $query_restrictions .= " AND relevanssi.doc IN (
1516
+ SELECT ID FROM $wpdb->posts WHERE 1=1
1517
+ AND (
1518
+ SELECT COUNT(1)
1519
+ FROM $wpdb->term_relationships AS tr
1520
+ WHERE tr.term_taxonomy_id IN ($local_and_term_tax_ids)
1521
+ AND tr.object_id = $wpdb->posts.ID ) = $n
1522
+ )";
1523
+ // Clean: all variables are Relevanssi-generated
1524
+ }
1525
+ }
1526
+
1527
+ $copy_term_tax_ids = false;
1528
+ if (!$is_sub_row) $copy_term_tax_ids = true;
1529
+ if ($is_sub_row && $global_relation == 'or') $copy_term_tax_ids = true;
1530
+
1531
+ if ($copy_term_tax_ids) {
1532
+ $term_tax_ids = array_merge($term_tax_ids, $local_term_tax_ids);
1533
+ $not_term_tax_ids = array_merge($not_term_tax_ids, $local_not_term_tax_ids);
1534
+ $and_term_tax_ids = array_merge($and_term_tax_ids, $local_and_term_tax_ids);
1535
+ }
1536
+
1537
+ return array($query_restrictions, $term_tax_ids, $not_term_tax_ids, $and_term_tax_ids);
1538
+ }
1539
+
1540
+
1541
  ?>
lib/uninstall.php CHANGED
@@ -2,15 +2,15 @@
2
 
3
  function relevanssi_clear_database_tables() {
4
  global $wpdb;
5
-
6
  if (defined('RELEVANSSI_PREMIUM')) return; // Relevanssi Premium exists, do not delete the tables
7
-
8
  wp_clear_scheduled_hook('relevanssi_truncate_cache');
9
 
10
- $relevanssi_table = $wpdb->prefix . "relevanssi";
11
  $stopword_table = $wpdb->prefix . "relevanssi_stopwords";
12
  $log_table = $wpdb->prefix . "relevanssi_log";
13
-
14
  if($wpdb->get_var("SHOW TABLES LIKE '$stopword_table'") == $stopword_table) {
15
  $sql = "DROP TABLE $stopword_table";
16
  $wpdb->query($sql);
@@ -27,4 +27,4 @@ function relevanssi_clear_database_tables() {
27
  }
28
  }
29
 
30
- ?>
2
 
3
  function relevanssi_clear_database_tables() {
4
  global $wpdb;
5
+
6
  if (defined('RELEVANSSI_PREMIUM')) return; // Relevanssi Premium exists, do not delete the tables
7
+
8
  wp_clear_scheduled_hook('relevanssi_truncate_cache');
9
 
10
+ $relevanssi_table = $wpdb->prefix . "relevanssi";
11
  $stopword_table = $wpdb->prefix . "relevanssi_stopwords";
12
  $log_table = $wpdb->prefix . "relevanssi_log";
13
+
14
  if($wpdb->get_var("SHOW TABLES LIKE '$stopword_table'") == $stopword_table) {
15
  $sql = "DROP TABLE $stopword_table";
16
  $wpdb->query($sql);
27
  }
28
  }
29
 
30
+ ?>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.relevanssi.com/buy-premium/
4
  Tags: search, relevance, better search
5
  Requires at least: 4.0
6
  Tested up to: 4.9
7
- Stable tag: 3.5.11.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -268,6 +268,10 @@ Each document database is full of useless words. All the little words that appea
268
 
269
  == Changelog ==
270
 
 
 
 
 
271
  = 3.5.11.1 =
272
  * New filter: `relevanssi_allow_one_letter_highlights` lets you allow one-letter highlights. Just make the filter function return `true`.
273
  * New filter: `relevanssi_block_one_letter_searches` by default blocks one-letter searches. If you want to enable them, add a filter function that always returns `false`.
@@ -1063,9 +1067,6 @@ Each document database is full of useless words. All the little words that appea
1063
 
1064
  == Upgrade notice ==
1065
 
1066
- = 3.5.11.1 =
1067
- * Minor bug fix, kills an error notice.
1068
-
1069
  = 3.5.11 =
1070
  * Improvements in excerpts, new filters.
1071
 
4
  Tags: search, relevance, better search
5
  Requires at least: 4.0
6
  Tested up to: 4.9
7
+ Stable tag: 3.5.12
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
268
 
269
  == Changelog ==
270
 
271
+ = 3.5.12 =
272
+ * Post type exclusion didn't work as expected.
273
+ * Relevanssi couldn't handle nested tax queries (such as those generated by WooCommerce product visibility filtering) properly.
274
+
275
  = 3.5.11.1 =
276
  * New filter: `relevanssi_allow_one_letter_highlights` lets you allow one-letter highlights. Just make the filter function return `true`.
277
  * New filter: `relevanssi_block_one_letter_searches` by default blocks one-letter searches. If you want to enable them, add a filter function that always returns `false`.
1067
 
1068
  == Upgrade notice ==
1069
 
 
 
 
1070
  = 3.5.11 =
1071
  * Improvements in excerpts, new filters.
1072
 
relevanssi.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Relevanssi
4
  Plugin URI: http://www.relevanssi.com/
5
  Description: This plugin replaces WordPress search with a relevance-sorting search.
6
- Version: 3.5.11.1
7
  Author: Mikko Saari
8
  Author URI: http://www.mikkosaari.fi/
9
  */
3
  Plugin Name: Relevanssi
4
  Plugin URI: http://www.relevanssi.com/
5
  Description: This plugin replaces WordPress search with a relevance-sorting search.
6
+ Version: 3.5.12
7
  Author: Mikko Saari
8
  Author URI: http://www.mikkosaari.fi/
9
  */