-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance improvements: rendering the Subscription Relationship column and checking if order is a renewal, switch etc. #732
Changes from 16 commits
dd1299a
44321ec
976c961
74a9e5a
fc91135
b8f94ab
adeaeca
1122373
ec44e56
de03e43
ad40418
7598c36
c6b4d21
ecf3bdf
6621e10
71baf7c
5f237ab
cd7ac49
4051a4c
9dd21cf
b4bcb76
d492796
1de39ec
05813de
d1ea790
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -68,21 +68,63 @@ function wcs_get_subscriptions_for_order( $order, $args = array() ) { | |
|
||
$all_relation_types = WCS_Related_Order_Store::instance()->get_relation_types(); | ||
$relation_types = $get_all ? $all_relation_types : array_intersect( $all_relation_types, $args['order_type'] ); | ||
$subscription_ids = wcs_get_subscription_ids_for_order( $order, $relation_types ); | ||
|
||
foreach ( $relation_types as $relation_type ) { | ||
|
||
$subscription_ids = WCS_Related_Order_Store::instance()->get_related_subscription_ids( $order, $relation_type ); | ||
|
||
foreach ( $subscription_ids as $subscription_id ) { | ||
if ( wcs_is_subscription( $subscription_id ) ) { | ||
$subscriptions[ $subscription_id ] = wcs_get_subscription( $subscription_id ); | ||
} | ||
foreach ( $subscription_ids as $subscription_id ) { | ||
if ( wcs_is_subscription( $subscription_id ) ) { | ||
$subscriptions[ $subscription_id ] = wcs_get_subscription( $subscription_id ); | ||
} | ||
} | ||
|
||
return $subscriptions; | ||
} | ||
|
||
/** | ||
* Get the subscription IDs for an order. | ||
* | ||
* @param WC_Order $order The order to get the subscription IDs for. | ||
* @param string|array $order_types The order types to get the subscription IDs for. | ||
* | ||
* @return array The subscription IDs. | ||
*/ | ||
function wcs_get_subscription_ids_for_order( $order, $order_types = [] ) { | ||
$subscription_ids = []; | ||
|
||
if ( ! is_a( $order, 'WC_Abstract_Order' ) ) { | ||
$order = wc_get_order( $order ); | ||
} | ||
|
||
if ( ! wcs_is_order( $order ) ) { | ||
return $subscription_ids; | ||
} | ||
|
||
if ( ! is_array( $order_types ) ) { | ||
$order_types = [ $order_types ]; | ||
} | ||
|
||
$valid_order_types = array_intersect( WCS_Related_Order_Store::instance()->get_relation_types(), $order_types ); | ||
|
||
foreach ( $valid_order_types as $order_type ) { | ||
$subscription_ids += WCS_Related_Order_Store::instance()->get_related_subscription_ids( $order, $order_type ); | ||
} | ||
|
||
// An order cannot be both a renewal, switch or resubscribe as well as a parent order, so only fetch subscription IDs if we didn't find any in the related order store. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we can make this assumption. If I resubscribe to a cancelled subscription, that order is a parent to the new subscription and a resubscribe to the old subscription. wcs_get_subscription_ids_for_order( $resubscribe_order, [ 'resubscribe', 'parent' ] ) This should return 2 results, the cancelled subscription and the new one. In it's current form, it would just return the resubscribe. I understand the intention is to avoid unnecessary expensive queries. I think callers if they were being super performance conscious, they would be be better off doing something like this: $related_subscriptions = wcs_get_subscription_ids_for_order( $order, [ 'resubscribe', 'renewal', 'switch' ] );
// If the subscription contains a subscription
if ( ! empty( $related_subscriptions ) || wcs_is_parent_order( $order ) {
... ie separate the related order relations from the parent check. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for flagging this! I've fixed this in 5f237ab |
||
if ( empty( $subscription_ids ) && in_array( 'parent', $order_types, true ) ) { | ||
$subscription_ids = wc_get_orders( | ||
[ | ||
'parent' => $order->get_id(), | ||
'type' => 'shop_subscription', | ||
'status' => 'any', | ||
'limit' => -1, | ||
'return' => 'ids', | ||
'orderby' => 'ID', | ||
] | ||
); | ||
} | ||
|
||
return $subscription_ids; | ||
} | ||
|
||
/** | ||
* Copy the billing, shipping or all addresses from one order or subscription to another. | ||
* | ||
|
@@ -365,10 +407,7 @@ function wcs_order_contains_subscription( $order, $order_type = array( 'parent', | |
$contains_subscription = false; | ||
$get_all = in_array( 'any', $order_type, true ); | ||
|
||
if ( ( in_array( 'parent', $order_type, true ) || $get_all ) && count( wcs_get_subscriptions_for_order( $order->get_id(), array( 'order_type' => 'parent' ) ) ) > 0 ) { | ||
$contains_subscription = true; | ||
|
||
} elseif ( ( in_array( 'renewal', $order_type, true ) || $get_all ) && wcs_order_contains_renewal( $order ) ) { | ||
if ( ( in_array( 'renewal', $order_type, true ) || $get_all ) && wcs_order_contains_renewal( $order ) ) { | ||
$contains_subscription = true; | ||
|
||
} elseif ( ( in_array( 'resubscribe', $order_type, true ) || $get_all ) && wcs_order_contains_resubscribe( $order ) ) { | ||
|
@@ -377,6 +416,8 @@ function wcs_order_contains_subscription( $order, $order_type = array( 'parent', | |
} elseif ( ( in_array( 'switch', $order_type, true ) || $get_all ) && wcs_order_contains_switch( $order ) ) { | ||
$contains_subscription = true; | ||
|
||
} elseif ( ( in_array( 'parent', $order_type, true ) || $get_all ) && wcs_is_parent_order( $order ) ) { | ||
$contains_subscription = true; | ||
} | ||
|
||
return $contains_subscription; | ||
|
@@ -1055,3 +1096,29 @@ function wcs_set_recurring_item_total( &$item ) { | |
] | ||
); | ||
} | ||
|
||
/** | ||
* Checks if an order is a Subscriptions parent/initial order. | ||
* | ||
* @param WC_Order|int $order The WC_Order object or ID of a WC_Order order. | ||
*/ | ||
function wcs_is_parent_order( $order ) { | ||
$order = ! is_object( $order ) ? wc_get_order( $order ) : $order; | ||
|
||
if ( ! $order || ! wcs_is_order( $order ) ) { | ||
return false; | ||
} | ||
|
||
// Check if the order ID is the parent of a subscription. | ||
$is_parent_order = wc_get_orders( | ||
[ | ||
'parent' => $order->get_id(), | ||
'type' => 'shop_subscription', | ||
'status' => 'any', | ||
'limit' => 1, | ||
'return' => 'ids', | ||
] | ||
); | ||
|
||
return apply_filters( 'woocommerce_subscriptions_is_parent_order', ! empty( $is_parent_order ), $order ); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,20 +21,8 @@ | |
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0 | ||
*/ | ||
function wcs_order_contains_resubscribe( $order ) { | ||
|
||
if ( ! is_a( $order, 'WC_Abstract_Order' ) ) { | ||
$order = wc_get_order( $order ); | ||
} | ||
|
||
$related_subscriptions = wcs_get_subscriptions_for_resubscribe_order( $order ); | ||
|
||
if ( wcs_is_order( $order ) && ! empty( $related_subscriptions ) ) { | ||
mattallan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$is_resubscribe_order = true; | ||
} else { | ||
$is_resubscribe_order = false; | ||
} | ||
|
||
return apply_filters( 'woocommerce_subscriptions_is_resubscribe_order', $is_resubscribe_order, $order ); | ||
$related_subscription_ids = wcs_get_subscription_ids_for_order( $order, 'resubscribe' ); | ||
return apply_filters( 'woocommerce_subscriptions_is_resubscribe_order', ! empty( $related_subscription_ids ), $order ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This applies to all the Unfortunately I think this means we will need to return to the if ( ! is_a( $order, 'WC_Abstract_Order' ) ) {
$order = wc_get_order( $order );
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch @james-allan! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just pushed up d492796 to address this! Going to run through some more tests on these latest changes |
||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the intention behind the empty
[]
$order_types
param?Passing an empty array returns no results. Is it supposed to be interpreted as all order types?
It's probably worth detailing this in the function block param comment too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @james-allan. I think it makes sense for us to return 'any' subscription IDs linked to the given order so I've just implemented the any param here cd7ac49.
I also added these default details to the docblock (see 4051a4c)