Closed james-allan closed 11 months ago
Regarding your feedback about there being 2 filters. That's basically by necessity. The existing hook (woocommerce_subscriptions_recurring_cart_key
) passes a cart item. Callbacks are able to fetch product data and cart context from that cart item to assist with generating a unique cart item key.
The new hook introduced in this PR, doesn't have access to a cart so cannot provide that kind of context. With that in mind the, two filters are basically incompatible with each other - 1 cannot be used to replace both. The only solution to resolve the two filter issue would be to deprecate the old one but there wouldn't be a backwards compatible hook.
To give you an example using the two features you mentioned - Gifting and Syncing.
Gifting requires the cart context. A product on it's own doesn't contain enough context to enable Gifting to separate gifted products in a cart by recipient. Being passed the cart item, it can locate the recipient cart item information and append it to the recurring cart key.
Sycning is product related - it doesn't require any cart information at all to be able to generate a key unique for a product so synced products can be grouped by the same key.
Deprecating the old filter would break Gifting with no alternative - it needs the cart item context. Not introducing this new hook breaks this new functionality because we do want to be able to split order items into subscription groups based on the product without a cart. eg synced or not synced.
There's no way around that other than the two hooks being separate. ie the two hooks wouldn't run in series, the cart one would run on the cart and the product one would run for the REST API context. That would resolve the two other issues you mentioned about the order of the key changing, and the risk if folks were unhooking callbacks etc.
I'm happy to take this approach but you mentioned you weren't keen on the two function approach, is there a reason behind that?
I couldn't find any hints as to why this hook needed to be on the earliest priority but maybe you might know.
I can't imagine it was hooked on early for any specific reason. The hook is used to generate a unique key by appending info to the string. So unless someone is splitting the key and expecting the order of the key to be something specific, the order that functions are hook onto this filter is irrelevant.
Thanks @james-allan for sharing your thoughts! Given there are some extensions like gifting that rely on cart item data and this new API endpoint requiring the product/order item, it looks like having just the one hook is never going to be possible (like I was hoping)
I'm happy to take this approach but you mentioned you weren't keen on the two-function approach, is there a reason behind that?
I don't recall exactly what I was thinking at the time of writing that comment but I think my original comment was an initial impression on having developers hook on twice for theoretically the same thing and I was probably hoping we could find a way to just have the 1 hook.
Taking into account the things you mention, I would say I'm leaning more towards having two separate hooks as that gives the most flexibility without functional downsides aside. I guess with two hooks, if the customisation only needs the product then they could get away with having one function that is hooked onto the two hooks.
@mattallan following our conversations about this I've done the following:
wcs_get_subscription_grouping_key()
woocommerce_subscriptions_item_grouping_key
. As it stands there are 3 filters with different use cases.
woocommerce_subscriptions_recurring_cart_key
- this is the OG hook and is unchanged. It's designed to be used by plugins like Gifting to ensure cart items with different recipients are separated into different subscriptions. woocommerce_subscriptions_item_grouping_key
- this is the equivalent of the cart item one (above) but for order items. Its second param is an order item, rather than a cart item. wcs_subscription_product_grouping_key
- this is a new hook and sits at the base of the two filters mentioned above. Rather than having a cart item or order item as it's context, it passes a product as the second param. This will be useful for plugins or code which don't have a specific need to filter the specific cart or order item context as it only requires a product to determine/alter the recurring cart item/subscription grouping key. Syncing could use this for example but isn't for backwards compatibility reasons.
Description
This PR refactors the
get_recurring_cart_key()
function so the functionality which groups subscription products/cart items into subscriptions with the same billing terms can be utilised in grouping order items into subscriptions. This change is necessary for a new REST API endpoint that will create subscriptions from parent order line items. See https://github.com/woocommerce/woocommerce-subscriptions/issues/4562How to test this PR
This PR should result in no direct change/impact.
Product impact