Skip to content

Commit b801133

Browse files
authored
fix: Products query "where.search" param patched (wp-graphql#903)
1 parent 22b03e4 commit b801133

File tree

2 files changed

+78
-3
lines changed

2 files changed

+78
-3
lines changed

includes/data/connection/class-product-connection-resolver.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,13 @@ public function get_query_args() {
239239
public function get_query() {
240240
add_filter( 'posts_clauses', [ $this->products_query, 'add_query_clauses' ], 10, 2 );
241241

242+
// Temporary fix for the search query.
243+
if ( ! empty( $this->query_args['search'] ) ) {
244+
$this->query_args['fulltext_search'] = $this->query_args['search'];
245+
unset( $this->query_args['search'] );
246+
add_filter( 'posts_clauses', [ $this, 'add_search_query_clause' ], 10, 2 );
247+
}
248+
242249
return new \WP_Query();
243250
}
244251

@@ -249,6 +256,10 @@ public function get_ids_from_query() {
249256
// Run query and get IDs.
250257
$ids = $this->query->query( $this->query_args );
251258

259+
if ( ! empty( $this->query_args['fulltext_search'] ) ) {
260+
remove_filter( 'posts_clauses', [ $this, 'add_search_query_clause' ], 10 );
261+
}
262+
252263
remove_filter( 'posts_clauses', [ $this->products_query, 'add_query_clauses' ], 10 );
253264

254265
// If we're going backwards, we need to reverse the array.
@@ -284,6 +295,30 @@ public function ordering_meta( $is_numeric = true ) {
284295
);
285296
}
286297

298+
/**
299+
* This function replaces the default product query search query clause with a clause searching the product's description, short description and slug.
300+
*
301+
* @param array $args The query arguments.
302+
* @param \WP_Query $wp_query The WP_Query object.
303+
* @return array
304+
*/
305+
public function add_search_query_clause( $args, $wp_query ) {
306+
global $wpdb;
307+
if ( empty( $wp_query->get( 'fulltext_search' ) ) ) {
308+
return $args;
309+
}
310+
311+
$search = '%' . $wpdb->esc_like( $wp_query->get( 'fulltext_search' ) ) . '%';
312+
$search_query = $wpdb->prepare( " AND ( $wpdb->posts.post_title LIKE %s OR $wpdb->posts.post_name LIKE %s OR wc_product_meta_lookup.sku LIKE %s OR $wpdb->posts.post_content LIKE %s OR $wpdb->posts.post_excerpt LIKE %s ) ", $search, $search, $search, $search, $search );
313+
$args['where'] .= $search_query;
314+
315+
if ( ! strstr( $args['join'], 'wc_product_meta_lookup' ) ) {
316+
$args['join'] .= " LEFT JOIN {$wpdb->wc_product_meta_lookup} wc_product_meta_lookup ON $wpdb->posts.ID = wc_product_meta_lookup.product_id ";
317+
}
318+
319+
return $args;
320+
}
321+
287322
/**
288323
* This sets up the "allowed" args, and translates the GraphQL-friendly keys to WP_Query
289324
* friendly keys. There's probably a cleaner/more dynamic way to approach this, but
@@ -309,6 +344,7 @@ public function sanitize_input_fields( array $where_args ) {
309344
'parentIn' => 'post_parent__in',
310345
'parentNotIn' => 'post_parent__not_in',
311346
'search' => 'search',
347+
312348
]
313349
);
314350

tests/wpunit/ProductsQueriesTest.php

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ private function createProducts() {
55
$products = [
66
$this->factory->product->createSimple([
77
'name' => 'Product Blue',
8+
'slug' => 'product-blue',
89
'description' => 'A peach description',
910
'price' => 100,
1011
'regular_price' => 100,
@@ -16,6 +17,7 @@ private function createProducts() {
1617
]),
1718
$this->factory->product->createSimple([
1819
'name' => 'Product Green',
20+
'slug' => 'product-green',
1921
'description' => 'A turquoise description',
2022
'sku' => 'green-sku',
2123
'price' => 200,
@@ -28,6 +30,7 @@ private function createProducts() {
2830
]),
2931
$this->factory->product->createSimple([
3032
'name' => 'Product Red',
33+
'slug' => 'product-red',
3134
'description' => 'A maroon description',
3235
'price' => 300,
3336
'regular_price' => 300,
@@ -39,6 +42,7 @@ private function createProducts() {
3942
]),
4043
$this->factory->product->createSimple([
4144
'name' => 'Product Yellow',
45+
'slug' => 'product-yellow',
4246
'description' => 'A teal description',
4347
'price' => 400,
4448
'regular_price' => 400,
@@ -50,6 +54,7 @@ private function createProducts() {
5054
]),
5155
$this->factory->product->createSimple([
5256
'name' => 'Product Purple',
57+
'slug' => 'product-purple',
5358
'description' => 'A magenta description',
5459
'price' => 500,
5560
'regular_price' => 500,
@@ -1024,6 +1029,8 @@ public function testProductsSearchArg() {
10241029
nodes {
10251030
id
10261031
name
1032+
description
1033+
sku
10271034
... on ProductWithPricing {
10281035
databaseId
10291036
price
@@ -1056,9 +1063,7 @@ public function testProductsSearchArg() {
10561063
/**
10571064
* Assert search by product sku.
10581065
*/
1059-
$variables = [
1060-
'search' => 'green-sku',
1061-
];
1066+
$variables = [ 'search' => 'green-sku' ];
10621067
$response = $this->graphql( compact( 'query', 'variables' ) );
10631068
$this->assertQuerySuccessful(
10641069
$response,
@@ -1071,7 +1076,41 @@ public function testProductsSearchArg() {
10711076
0
10721077
),
10731078
],
1079+
'Failed to search products by product sku.'
1080+
);
1081+
1082+
// Search by product description.
1083+
$variables = [ 'search' => 'magenta' ];
1084+
$response = $this->graphql( compact( 'query', 'variables' ) );
1085+
$this->assertQuerySuccessful(
1086+
$response,
1087+
[
1088+
$this->expectedNode(
1089+
'products.nodes',
1090+
[
1091+
$this->expectedField( 'id', $this->toRelayId( 'post', $products[4] ) )
1092+
],
1093+
0
1094+
),
1095+
],
10741096
'Failed to search products by product description content.'
10751097
);
1098+
1099+
// Search by slug.
1100+
$variables = [ 'search' => 'product-red' ];
1101+
$response = $this->graphql( compact( 'query', 'variables' ) );
1102+
$this->assertQuerySuccessful(
1103+
$response,
1104+
[
1105+
$this->expectedNode(
1106+
'products.nodes',
1107+
[
1108+
$this->expectedField( 'id', $this->toRelayId( 'post', $products[2] ) )
1109+
],
1110+
0
1111+
),
1112+
],
1113+
'Failed to search products by product slug.'
1114+
);
10761115
}
10771116
}

0 commit comments

Comments
 (0)