Support `wc_customer_bought_product` for hpos. (#34931)
* Support `wc_customer_bought_product` for hpos. * Apply code standards.
This commit is contained in:
parent
17c8a7fb0a
commit
82153ea567
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: add
|
||||
|
||||
Support `wc_customer_bought_product` function in HPOS.
|
|
@ -8,6 +8,9 @@
|
|||
* @version 2.2.0
|
||||
*/
|
||||
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
||||
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
|
@ -344,19 +347,40 @@ function wc_customer_bought_product( $customer_email, $user_id, $product_id ) {
|
|||
return false;
|
||||
}
|
||||
|
||||
$result = $wpdb->get_col(
|
||||
"
|
||||
SELECT im.meta_value FROM {$wpdb->posts} AS p
|
||||
INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id
|
||||
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS i ON p.ID = i.order_id
|
||||
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS im ON i.order_item_id = im.order_item_id
|
||||
WHERE p.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' )
|
||||
AND pm.meta_key IN ( '_billing_email', '_customer_user' )
|
||||
AND im.meta_key IN ( '_product_id', '_variation_id' )
|
||||
AND im.meta_value != 0
|
||||
AND pm.meta_value IN ( '" . implode( "','", $customer_data ) . "' )
|
||||
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||
$statuses = array_map(
|
||||
function ( $status ) {
|
||||
return "wc-$status";
|
||||
},
|
||||
$statuses
|
||||
);
|
||||
$order_table = OrdersTableDataStore::get_orders_table_name();
|
||||
$sql = "
|
||||
SELECT im.meta_value FROM $order_table AS o
|
||||
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS i ON o.id = i.order_id
|
||||
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS im ON i.order_item_id = im.order_item_id
|
||||
WHERE o.status IN ('" . implode( "','", $statuses ) . "')
|
||||
AND im.meta_key IN ('_product_id', '_variation_id' )
|
||||
AND im.meta_value != 0
|
||||
AND ( o.customer_id IN ('" . implode( "','", $customer_data ) . "') OR o.billing_email IN ('" . implode( "','", $customer_data ) . "') )
|
||||
|
||||
";
|
||||
$result = $wpdb->get_col( $sql );
|
||||
} else {
|
||||
$result = $wpdb->get_col(
|
||||
"
|
||||
SELECT im.meta_value FROM {$wpdb->posts} AS p
|
||||
INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id
|
||||
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS i ON p.ID = i.order_id
|
||||
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS im ON i.order_item_id = im.order_item_id
|
||||
WHERE p.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' )
|
||||
AND pm.meta_key IN ( '_billing_email', '_customer_user' )
|
||||
AND im.meta_key IN ( '_product_id', '_variation_id' )
|
||||
AND im.meta_value != 0
|
||||
AND pm.meta_value IN ( '" . implode( "','", $customer_data ) . "' )
|
||||
"
|
||||
); // WPCS: unprepared SQL ok.
|
||||
); // WPCS: unprepared SQL ok.
|
||||
}
|
||||
$result = array_map( 'absint', $result );
|
||||
|
||||
$transient_value = array(
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\RestApi\UnitTests;
|
||||
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
||||
use Automattic\WooCommerce\Internal\Features\FeaturesController;
|
||||
use Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper;
|
||||
use WC_Data_Store;
|
||||
|
||||
/**
|
||||
* Trait HPOSToggleTrait.
|
||||
*
|
||||
* Provides methods to toggle the HPOS feature on and off.
|
||||
*/
|
||||
trait HPOSToggleTrait {
|
||||
|
||||
/**
|
||||
* Call in setUp to enable COT/HPOS.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setup_cot() {
|
||||
// Remove the Test Suite’s use of temporary tables https://wordpress.stackexchange.com/a/220308.
|
||||
remove_filter( 'query', array( $this, '_create_temporary_tables' ) );
|
||||
remove_filter( 'query', array( $this, '_drop_temporary_tables' ) );
|
||||
OrderHelper::delete_order_custom_tables();
|
||||
OrderHelper::create_order_custom_table_if_not_exist();
|
||||
|
||||
$this->toggle_cot( true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Call in teardown to disable COT/HPOS.
|
||||
*/
|
||||
public function clean_up_cot_setup(): void {
|
||||
$this->toggle_cot( false );
|
||||
|
||||
// Add back removed filter.
|
||||
add_filter( 'query', array( $this, '_create_temporary_tables' ) );
|
||||
add_filter( 'query', array( $this, '_drop_temporary_tables' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables the custom orders table across WP temporarily.
|
||||
*
|
||||
* @param boolean $enabled TRUE to enable COT or FALSE to disable.
|
||||
* @return void
|
||||
*/
|
||||
private function toggle_cot( bool $enabled ): void {
|
||||
$features_controller = wc_get_container()->get( Featurescontroller::class );
|
||||
$features_controller->change_feature_enable( 'custom_order_tables', true );
|
||||
|
||||
update_option( CustomOrdersTableController::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION, wc_bool_to_string( $enabled ) );
|
||||
|
||||
// Confirm things are really correct.
|
||||
$wc_data_store = WC_Data_Store::load( 'order' );
|
||||
assert( is_a( $wc_data_store->get_current_class_name(), OrdersTableDataStore::class, true ) === $enabled );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
use Automattic\WooCommerce\RestApi\UnitTests\HPOSToggleTrait;
|
||||
|
||||
/**
|
||||
* Tests for the WC_User class.
|
||||
*/
|
||||
class WC_User_Functions_Tests extends WC_Unit_Test_Case {
|
||||
use HPOSToggleTrait;
|
||||
|
||||
/**
|
||||
* Setup COT.
|
||||
*/
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->setup_cot();
|
||||
$this->toggle_cot( false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean COT specific things.
|
||||
*/
|
||||
public function tearDown(): void {
|
||||
parent::tearDown();
|
||||
$this->clean_up_cot_setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test wc_get_customer_order_count. Borrowed from `WC_Tests_Customer_Functions` class for COT.
|
||||
*/
|
||||
public function test_hpos_wc_customer_bought_product() {
|
||||
$this->toggle_cot( true );
|
||||
$customer_id_1 = wc_create_new_customer( 'test@example.com', 'testuser', 'testpassword' );
|
||||
$customer_id_2 = wc_create_new_customer( 'test2@example.com', 'testuser2', 'testpassword2' );
|
||||
$product_1 = new WC_Product_Simple();
|
||||
$product_1->save();
|
||||
$product_id_1 = $product_1->get_id();
|
||||
$product_2 = new WC_Product_Simple();
|
||||
$product_2->save();
|
||||
$product_id_2 = $product_2->get_id();
|
||||
|
||||
$order_1 = WC_Helper_Order::create_order( $customer_id_1, $product_1 );
|
||||
$order_1->set_billing_email( 'test@example.com' );
|
||||
$order_1->set_status( 'completed' );
|
||||
$order_1->save();
|
||||
$order_2 = WC_Helper_Order::create_order( $customer_id_2, $product_2 );
|
||||
$order_2->set_billing_email( 'test2@example.com' );
|
||||
$order_2->set_status( 'completed' );
|
||||
$order_2->save();
|
||||
$order_3 = WC_Helper_Order::create_order( $customer_id_1, $product_2 );
|
||||
$order_3->set_billing_email( 'test@example.com' );
|
||||
$order_3->set_status( 'pending' );
|
||||
$order_3->save();
|
||||
|
||||
$this->assertTrue( wc_customer_bought_product( 'test@example.com', $customer_id_1, $product_id_1 ) );
|
||||
$this->assertTrue( wc_customer_bought_product( '', $customer_id_1, $product_id_1 ) );
|
||||
$this->assertTrue( wc_customer_bought_product( 'test@example.com', 0, $product_id_1 ) );
|
||||
$this->assertFalse( wc_customer_bought_product( 'test@example.com', $customer_id_1, $product_id_2 ) );
|
||||
$this->assertFalse( wc_customer_bought_product( 'test2@example.com', $customer_id_2, $product_id_1 ) );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue