Automattic / woocommerce-subscriptions-core

Subscriptions core package for WooCommerce
Other
85 stars 31 forks source link

Merge meta queries as part of wcs_get_orders_with_meta_query() rather than override them #353

Closed james-allan closed 1 year ago

james-allan commented 1 year ago

Fixes #346

Description

I'm not aware of a user flow that directly leads to this issue however, given our documented APIs are broken and its an easy fix, we should fix with priority. This does mean the testing instructions will be dev in nature.

In https://github.com/Automattic/woocommerce-subscriptions-core/pull/171 we introduced a helper function for fetching orders or subscriptions with a meta query in a HPOS and CPT compatible way.

This resulted in the function wcs_get_orders_with_meta_query() which will map a custom meta_query onto WC core's wc_get_orders() query via the woocommerce_order_data_store_cpt_get_orders_query hook on CPT stores.

In our approach however, any pre-existing meta query value that WC core set, would be overridden.

In CPT, WC core will map wc_get_orders() args onto the meta_query arg when querying by any internal meta key (eg order_currency, order_total), or a handful of other keys like customer or anonymized.

This means that when you call wcs_get_orders_with_meta_query() with a custom meta query with any key that WC core maps to meta_query, you'll get incorrect results.

This PR fixes that by making sure we merge the custom meta query with WC core one, if it exists.

How to test this PR

  1. Set your store to CPT (not HPOS)
  2. Purchase at least 1 subscription using 1 account.
  3. Purchase at least 1 subscription using a different account.
  4. Run the following code on your site.
    • On trunk you'll get both customer subscriptions returned even though you're filtering by a specific customer.
    • On this branch you'll get only get 1 customer subscription.
// Get a customer's subscriptions without a trial
$subscription_query_args = [
    'customer_id'            => 1, // <- change this customer ID if you have a different one
    'subscription_status'    => 'active',
    'subscriptions_per_page' => -1,
    'meta_query'             => [
        [
            'key'     => '_schedule_trial_end',
            'compare' => '=',
            'value'   => 0,
        ],
    ],
];

echo count( wcs_get_subscriptions( $subscription_query_args ) );

Product impact

lkraav commented 1 year ago

Thanks all. If I'm silent here, means it must be working :)