Update product searching to search by name or sku (https://github.com/woocommerce/woocommerce-admin/pull/1791)

* Add product search option REST API

* Remove join and where filters for wp_query after rest response

* Remove product_name search in favor of sku and name searching

* Allow searching for products to compare by product sku

* Search by product search term instead of generic search in autocompleter

* Trim whitespace on product_search query

* Override existing search param instead of new param

* Use double quotes to avoid escaping search query

* Unset s param instead of setting to false
This commit is contained in:
Joshua T Flowers 2019-03-18 11:31:02 +08:00 committed by GitHub
parent 2187f0e1bc
commit 7653859509
2 changed files with 40 additions and 17 deletions

View File

@ -55,17 +55,18 @@ class WC_Admin_REST_Products_Controller extends WC_REST_Products_Controller {
* @return array * @return array
*/ */
public function get_collection_params() { public function get_collection_params() {
$params = parent::get_collection_params(); $params = parent::get_collection_params();
$params['product_name'] = array( $params['search'] = array(
'description' => __( 'Search for a similar product name.', 'woocommerce-admin' ), 'description' => __( 'Search by similar product name or sku.', 'woocommerce-admin' ),
'type' => 'string', 'type' => 'string',
'validate_callback' => 'rest_validate_request_arg', 'validate_callback' => 'rest_validate_request_arg',
); );
return $params; return $params;
} }
/** /**
* Add product name filtering to the WC API. * Add product name and sku filtering to the WC API.
* *
* @param WP_REST_Request $request Request data. * @param WP_REST_Request $request Request data.
* @return array * @return array
@ -73,8 +74,9 @@ class WC_Admin_REST_Products_Controller extends WC_REST_Products_Controller {
protected function prepare_objects_query( $request ) { protected function prepare_objects_query( $request ) {
$args = parent::prepare_objects_query( $request ); $args = parent::prepare_objects_query( $request );
if ( ! empty( $request['product_name'] ) ) { if ( ! empty( $request['search'] ) ) {
$args['post_title__like'] = $request['product_name']; $args['search'] = $request['search'];
unset( $args['s'] );
} }
return $args; return $args;
@ -87,30 +89,51 @@ class WC_Admin_REST_Products_Controller extends WC_REST_Products_Controller {
* @return WP_Error|WP_REST_Response * @return WP_Error|WP_REST_Response
*/ */
public function get_items( $request ) { public function get_items( $request ) {
add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_post_title_filter' ), 10, 2 ); add_filter( 'posts_where', array( __CLASS__, 'add_wp_query_product_search_filter' ), 10, 2 );
add_filter( 'posts_join', array( __CLASS__, 'add_wp_query_product_search_join' ), 10, 2 );
$response = parent::get_items( $request ); $response = parent::get_items( $request );
remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_post_title_filter' ), 10 ); remove_filter( 'posts_where', array( __CLASS__, 'add_wp_query_product_search_filter' ), 10 );
remove_filter( 'posts_join', array( __CLASS__, 'add_wp_query_product_search_join' ), 10 );
return $response; return $response;
} }
/** /**
* Add post title searching to WP Query * Allow searching by product name or sku in WP Query
* *
* @param string $where Where clause used to search posts. * @param string $where Where clause used to search posts.
* @param object $wp_query WP_Query object. * @param object $wp_query WP_Query object.
* @return string * @return string
*/ */
public static function add_wp_query_post_title_filter( $where, $wp_query ) { public static function add_wp_query_product_search_filter( $where, $wp_query ) {
global $wpdb; global $wpdb;
$post_title_search = $wp_query->get( 'post_title__like' ); $search = trim( $wp_query->get( 'search' ) );
if ( $post_title_search ) { if ( $search ) {
$post_title_search = $wpdb->esc_like( $post_title_search ); $search = $wpdb->esc_like( $search );
$post_title_search = ' \'%' . $post_title_search . '%\''; $search = "'%" . $search . "%'";
$where .= ' AND ' . $wpdb->posts . '.post_title LIKE ' . $post_title_search; $where .= ' AND (' . $wpdb->posts . '.post_title LIKE ' . $search;
$where .= wc_product_sku_enabled() ? ' OR ps_post_meta.meta_key = "_sku" AND ps_post_meta.meta_value LIKE ' . $search . ')' : ')';
} }
return $where; return $where;
} }
/**
* Join posts meta table when product search is present and meta query is not present.
*
* @param string $join Join clause used to search posts.
* @param object $wp_query WP_Query object.
* @return string
*/
public static function add_wp_query_product_search_join( $join, $wp_query ) {
global $wpdb;
$search = trim( $wp_query->get( 'search' ) );
if ( $search && wc_product_sku_enabled() ) {
$join .= ' INNER JOIN ' . $wpdb->postmeta . ' AS ps_post_meta ON ps_post_meta.post_id = ' . $wpdb->posts . '.ID';
}
return $join;
}
} }

View File

@ -30,7 +30,7 @@ export default {
let payload = ''; let payload = '';
if ( search ) { if ( search ) {
const query = { const query = {
product_name: search, search: search,
per_page: 10, per_page: 10,
orderby: 'popularity', orderby: 'popularity',
}; };
@ -40,7 +40,7 @@ export default {
}, },
isDebounced: true, isDebounced: true,
getOptionKeywords( product ) { getOptionKeywords( product ) {
return [ product.name ]; return [ product.name, product.sku ];
}, },
getFreeTextOptions( query ) { getFreeTextOptions( query ) {
const label = ( const label = (