Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions includes/data/connection/class-product-connection-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,13 @@ public function get_query_args() {
public function get_query() {
add_filter( 'posts_clauses', [ $this->products_query, 'add_query_clauses' ], 10, 2 );

// Temporary fix for the search query.
if ( ! empty( $this->query_args['search'] ) ) {
$this->query_args['fulltext_search'] = $this->query_args['search'];
unset( $this->query_args['search'] );
add_filter( 'posts_clauses', [ $this, 'add_search_query_clause' ], 10, 2 );
}

return new \WP_Query();
}

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

if ( ! empty( $this->query_args['fulltext_search'] ) ) {
remove_filter( 'posts_clauses', [ $this, 'add_search_query_clause' ], 10 );
}

remove_filter( 'posts_clauses', [ $this->products_query, 'add_query_clauses' ], 10 );

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

/**
* This function replaces the default product query search query clause with a clause searching the product's description, short description and slug.
*
* @param array $args The query arguments.
* @param \WP_Query $wp_query The WP_Query object.
* @return array
*/
public function add_search_query_clause( $args, $wp_query ) {
global $wpdb;
if ( empty( $wp_query->get( 'fulltext_search' ) ) ) {
return $args;
}

$search = '%' . $wpdb->esc_like( $wp_query->get( 'fulltext_search' ) ) . '%';
$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 );
$args['where'] .= $search_query;

if ( ! strstr( $args['join'], 'wc_product_meta_lookup' ) ) {
$args['join'] .= " LEFT JOIN {$wpdb->wc_product_meta_lookup} wc_product_meta_lookup ON $wpdb->posts.ID = wc_product_meta_lookup.product_id ";
}

return $args;
}

/**
* This sets up the "allowed" args, and translates the GraphQL-friendly keys to WP_Query
* friendly keys. There's probably a cleaner/more dynamic way to approach this, but
Expand All @@ -309,6 +344,7 @@ public function sanitize_input_fields( array $where_args ) {
'parentIn' => 'post_parent__in',
'parentNotIn' => 'post_parent__not_in',
'search' => 'search',

]
);

Expand Down
45 changes: 42 additions & 3 deletions tests/wpunit/ProductsQueriesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ private function createProducts() {
$products = [
$this->factory->product->createSimple([
'name' => 'Product Blue',
'slug' => 'product-blue',
'description' => 'A peach description',
'price' => 100,
'regular_price' => 100,
Expand All @@ -16,6 +17,7 @@ private function createProducts() {
]),
$this->factory->product->createSimple([
'name' => 'Product Green',
'slug' => 'product-green',
'description' => 'A turquoise description',
'sku' => 'green-sku',
'price' => 200,
Expand All @@ -28,6 +30,7 @@ private function createProducts() {
]),
$this->factory->product->createSimple([
'name' => 'Product Red',
'slug' => 'product-red',
'description' => 'A maroon description',
'price' => 300,
'regular_price' => 300,
Expand All @@ -39,6 +42,7 @@ private function createProducts() {
]),
$this->factory->product->createSimple([
'name' => 'Product Yellow',
'slug' => 'product-yellow',
'description' => 'A teal description',
'price' => 400,
'regular_price' => 400,
Expand All @@ -50,6 +54,7 @@ private function createProducts() {
]),
$this->factory->product->createSimple([
'name' => 'Product Purple',
'slug' => 'product-purple',
'description' => 'A magenta description',
'price' => 500,
'regular_price' => 500,
Expand Down Expand Up @@ -1024,6 +1029,8 @@ public function testProductsSearchArg() {
nodes {
id
name
description
sku
... on ProductWithPricing {
databaseId
price
Expand Down Expand Up @@ -1056,9 +1063,7 @@ public function testProductsSearchArg() {
/**
* Assert search by product sku.
*/
$variables = [
'search' => 'green-sku',
];
$variables = [ 'search' => 'green-sku' ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$this->assertQuerySuccessful(
$response,
Expand All @@ -1071,7 +1076,41 @@ public function testProductsSearchArg() {
0
),
],
'Failed to search products by product sku.'
);

// Search by product description.
$variables = [ 'search' => 'magenta' ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$this->assertQuerySuccessful(
$response,
[
$this->expectedNode(
'products.nodes',
[
$this->expectedField( 'id', $this->toRelayId( 'post', $products[4] ) )
],
0
),
],
'Failed to search products by product description content.'
);

// Search by slug.
$variables = [ 'search' => 'product-red' ];
$response = $this->graphql( compact( 'query', 'variables' ) );
$this->assertQuerySuccessful(
$response,
[
$this->expectedNode(
'products.nodes',
[
$this->expectedField( 'id', $this->toRelayId( 'post', $products[2] ) )
],
0
),
],
'Failed to search products by product slug.'
);
}
}
Loading