Skip to content

Commit

Permalink
add tests for variations search
Browse files Browse the repository at this point in the history
  • Loading branch information
kilbot committed Nov 30, 2023
1 parent 1f0fd6b commit fa14938
Show file tree
Hide file tree
Showing 8 changed files with 504 additions and 231 deletions.
90 changes: 43 additions & 47 deletions includes/API/Customers_Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace WCPOS\WooCommercePOS\API;

\defined('ABSPATH') || die;
\defined( 'ABSPATH' ) || die;

if ( ! class_exists('WC_REST_Customers_Controller') ) {
if ( ! class_exists( 'WC_REST_Customers_Controller' ) ) {
return;
}

Expand All @@ -25,6 +25,7 @@
class Customers_Controller extends WC_REST_Customers_Controller {
use Traits\Uuid_Handler;
use Traits\WCPOS_REST_API;
use Traits\Query_Helpers;

/**
* Endpoint namespace.
Expand Down Expand Up @@ -58,8 +59,8 @@ public function get_item_schema() {
$schema = parent::get_item_schema();

// Check and remove email format validation from the billing property
if (isset($schema['properties']['billing']['properties']['email']['format'])) {
unset($schema['properties']['billing']['properties']['email']['format']);
if ( isset( $schema['properties']['billing']['properties']['email']['format'] ) ) {
unset( $schema['properties']['billing']['properties']['email']['format'] );
}

return $schema;
Expand All @@ -73,7 +74,7 @@ public function get_collection_params() {
$params = parent::get_collection_params();

// Check if 'orderby' is set and is an array before modifying it
if (isset($params['orderby']) && \is_array($params['orderby']['enum'])) {
if ( isset( $params['orderby'] ) && \is_array( $params['orderby']['enum'] ) ) {
// Add new fields to the 'orderby' enum list
$new_orderby_options = array(
'first_name',
Expand All @@ -82,8 +83,8 @@ public function get_collection_params() {
'role',
'username',
);
foreach ($new_orderby_options as $option) {
if ( ! \in_array($option, $params['orderby']['enum'], true)) {
foreach ( $new_orderby_options as $option ) {
if ( ! \in_array( $option, $params['orderby']['enum'], true ) ) {
$params['orderby']['enum'][] = $option;
}
}
Expand Down Expand Up @@ -137,14 +138,14 @@ public function update_item( $request ) {
public function wcpos_validate_billing_email( WP_REST_Request $request ) {
// Your custom validation logic for the request data
$billing = $request['billing'] ?? null;
$email = \is_array($billing) ? ($billing['email'] ?? null) : null;
if ( ! \is_null($email) && '' !== $email && ! is_email( $email ) ) {
$email = \is_array( $billing ) ? ( $billing['email'] ?? null ) : null;

if ( ! \is_null( $email ) && '' !== $email && ! is_email( $email ) ) {
return new \WP_Error(
'rest_invalid_param',
// translators: Use default WordPress translation
__( 'Invalid email address.' ),
array('status' => 400)
array( 'status' => 400 )
);
}

Expand Down Expand Up @@ -205,18 +206,24 @@ public function wcpos_customer_response( WP_REST_Response $response, WP_User $us
$customer = new WC_Customer( $user_data->ID );
$raw_meta_data = $customer->get_meta_data();

$filtered_meta_data = array_filter($raw_meta_data, function ($meta) {
return '_woocommerce_pos_uuid' === $meta->key;
});
$filtered_meta_data = array_filter(
$raw_meta_data,
function ( $meta ) {
return '_woocommerce_pos_uuid' === $meta->key;
}
);

// Convert to WC REST API expected format
$data['meta_data'] = array_map(function ($meta) {
return array(
'id' => $meta->id,
'key' => $meta->key,
'value' => $meta->value,
);
}, array_values($filtered_meta_data));
$data['meta_data'] = array_map(
function ( $meta ) {
return array(
'id' => $meta->id,
'key' => $meta->key,
'value' => $meta->value,
);
},
array_values( $filtered_meta_data )
);
} catch ( Exception $e ) {
Logger::log( 'Error getting customer meta data: ' . $e->getMessage() );
}
Expand Down Expand Up @@ -277,18 +284,18 @@ public function wcpos_get_all_posts( array $fields = array() ): array {
public function wcpos_customer_query( array $prepared_args, WP_REST_Request $request ): array {
$query_params = $request->get_query_params();

// Existing meta query
$existing_meta_query = $prepared_args['meta_query'] ?? array();

// add modified_after date_modified_gmt
if ( isset( $query_params['modified_after'] ) && '' !== $query_params['modified_after'] ) {
$timestamp = strtotime( $query_params['modified_after'] );
$prepared_args['meta_query'] = array(
$prepared_args['meta_query'] = $this->wcpos_combine_meta_queries(
array(
'key' => 'last_update',
'value' => $timestamp ? (string) $timestamp : '',
'compare' => '>',
array(
'key' => 'last_update',
'value' => $timestamp ? (string) $timestamp : '',
'compare' => '>',
),
),
$prepared_args['meta_query']
);
}

Expand Down Expand Up @@ -340,7 +347,7 @@ public function wcpos_customer_query( array $prepared_args, WP_REST_Request $req
unset( $prepared_args['search'] );
$prepared_args['_wcpos_search'] = $search_keyword; // store the search keyword for later use
add_action( 'pre_user_query', array( $this, 'wcpos_search_user_table' ) );

$search_meta_query = array(
'relation' => 'OR',
array(
Expand Down Expand Up @@ -380,21 +387,10 @@ public function wcpos_customer_query( array $prepared_args, WP_REST_Request $req
'compare' => 'LIKE',
),
);

// Merge with existing meta_query if any
if ( ! empty($existing_meta_query)) {
$existing_meta_query = array(
'relation' => 'AND',
$existing_meta_query,
$search_meta_query,
);
} else {
$existing_meta_query = $search_meta_query;
}
}

// Apply the modified or newly created meta_query
$prepared_args['meta_query'] = $existing_meta_query;
// Combine the search meta_query with the existing meta_query
$prepared_args['meta_query'] = $this->wcpos_combine_meta_queries( $search_meta_query, $prepared_args['meta_query'] );
}

return $prepared_args;
}
Expand All @@ -406,7 +402,7 @@ public function wcpos_customer_query( array $prepared_args, WP_REST_Request $req
*/
public function wcpos_search_user_table( $query ): void {
global $wpdb;

// Remove the hook
remove_action( 'pre_user_query', array( $this, 'wcpos_search_user_table' ) );

Expand All @@ -417,7 +413,7 @@ public function wcpos_search_user_table( $query ): void {
// Prepare the LIKE statement
$like_email = '%' . $wpdb->esc_like( $search_keyword ) . '%';
$like_login = '%' . $wpdb->esc_like( $search_keyword ) . '%';

$insertion = $wpdb->prepare(
"({$wpdb->users}.user_email LIKE %s) OR ({$wpdb->users}.user_login LIKE %s) OR ",
$like_email,
Expand All @@ -427,10 +423,10 @@ public function wcpos_search_user_table( $query ): void {
$pattern = "/\(\s*\w+\.meta_key\s*=\s*'[^']+'\s*AND\s*\w+\.meta_value\s*LIKE\s*'[^']+'\s*\)(\s*OR\s*\(\s*\w+\.meta_key\s*=\s*'[^']+'\s*AND\s*\w+\.meta_value\s*LIKE\s*'[^']+'\s*\))*\s*/";

// Add the search keyword to the query
$modified_where = preg_replace($pattern, "$insertion$0", $query->query_where);
$modified_where = preg_replace( $pattern, "$insertion$0", $query->query_where );
// Check if the replacement was successful and assign it back to query_where
if ($modified_where !== $query->query_where) {
if ( $modified_where !== $query->query_where ) {
$query->query_where = $modified_where;
}
}
Expand Down
104 changes: 70 additions & 34 deletions includes/API/Product_Variations_Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class Product_Variations_Controller extends WC_REST_Product_Variations_Controlle
use Traits\Product_Helpers;
use Traits\Uuid_Handler;
use Traits\WCPOS_REST_API;
use Traits\Query_Helpers;

/**
* Endpoint namespace.
Expand Down Expand Up @@ -288,7 +289,7 @@ protected function prepare_objects_query( $request ) {

// Add online_only check
if ( $this->wcpos_pos_only_products_enabled() ) {
$default_meta_query = array(
$meta_query = array(
'relation' => 'OR',
array(
'key' => '_pos_visibility',
Expand All @@ -301,56 +302,91 @@ protected function prepare_objects_query( $request ) {
),
);

if ( isset( $args['meta_query'] ) ) {
if ( ! isset( $args['meta_query']['relation'] ) ) {
$args['meta_query']['relation'] = 'AND';
}
$args['meta_query'] = array_merge_recursive( $args['meta_query'], $default_meta_query );
} else {
$args['meta_query'] = $default_meta_query;
}
// Combine meta queries
$args['meta_query'] = $this->wcpos_combine_meta_queries( $args['meta_query'], $meta_query );

};

return $args;
}

/**
* Endpoint for searching all product variations.
* Endpoint for getting all product variations, eg: search for sku or barcode.
*
* @param WP_REST_Request $request Full details about the request.
*/
public function wcpos_get_all_items( $request ) {
// Prepare arguments for the product query
$args = array(
'post_type' => 'product_variation',
'posts_per_page' => 10, // Limit to 10 items per page
'orderby' => 'ID', // Default ordering
'order' => 'ASC',
'paged' => ! empty( $request['page'] ) ? $request['page'] : 1, // Handle pagination
);
$query_args = $this->prepare_objects_query( $request );
if ( is_wp_error( current( $query_args ) ) ) {
return current( $query_args );
}

// Check if 'search' param is set for SKU search
if ( ! empty( $request['search'] ) ) {
$args['meta_query'] = array(
array(
'key' => '_sku',
'value' => $request['search'],
'compare' => 'LIKE',
),
if ( ! empty( $query_args['s'] ) ) {
$barcode_field = $this->wcpos_get_barcode_field();
$meta_query = array(
'key' => '_sku',
'value' => $query_args['s'],
'compare' => 'LIKE',
);

if ( $barcode_field && '_sku' !== $barcode_field ) {
$meta_query = array(
'relation' => 'OR',
$meta_query,
array(
'key' => $barcode_field,
'value' => $query_args['s'],
'compare' => 'LIKE',
),
);
}

// Combine meta queries
$query_args['meta_query'] = $this->wcpos_combine_meta_queries( $query_args['meta_query'], $meta_query );

unset( $query_args['s'] );
}

$query_results = $this->get_objects( $query_args );

$objects = array();
foreach ( $query_results['objects'] as $object ) {
if ( ! \wc_rest_check_post_permissions( $this->post_type, 'read', $object->get_id() ) ) {
continue;
}

$data = $this->prepare_object_for_response( $object, $request );
$objects[] = $this->prepare_response_for_collection( $data );
}

// Get product variations
$query = new WP_Query( $args );
$variations = array();
$page = (int) $query_args['paged'];
$max_pages = $query_results['pages'];

foreach ( $query->posts as $variation ) {
$object = new WC_Product_Variation( $variation->ID );
$response = $this->prepare_object_for_response( $object, $request );
$variations[] = $this->prepare_response_for_collection( $response );
$response = rest_ensure_response( $objects );
$response->header( 'X-WP-Total', $query_results['total'] );
$response->header( 'X-WP-TotalPages', (int) $max_pages );

/**
* Note: custom endpoint for getting all product variations
*/
$base = 'products/variations';
$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ) );

if ( $page > 1 ) {
$prev_page = $page - 1;
if ( $prev_page > $max_pages ) {
$prev_page = $max_pages;
}
$prev_link = add_query_arg( 'page', $prev_page, $base );
$response->link_header( 'prev', $prev_link );
}
if ( $max_pages > $page ) {
$next_page = $page + 1;
$next_link = add_query_arg( 'page', $next_page, $base );
$response->link_header( 'next', $next_link );
}

// Return the response
return new WP_REST_Response( $variations, 200 );
return $response;
}
}
Loading

0 comments on commit fa14938

Please sign in to comment.