问题
I'm trying to set a subscription trial length dynamically, depending on the combination of product variation and custom field options selected when the product is added to the cart.
For one product variation, there's a choice to either pay immediately, or to defer the first payment until the start of the new year. That option is selected via a custom radio button field. For all other product variations, payment is automatically deferred.
It's simple enough to set a default trial length for the product itself using
add_filter( 'woocommerce_subscriptions_product_trial_length', 'stc_woocommerce_subscriptions_product_trial_length', 10, 2 );
function stc_woocommerce_subscriptions_product_trial_length( $subscription_trial_length, $product ){
// Do the calculations based on the current date, product_id, &c. and return a revised $subscription_trial_length as needed
}
but I can't figure out how to set the trial_length to zero for the "pay immediately" option.
The most likely tool for setting/updating the subscription_trial_length seems to be wcs_set_objects_property
, though I've tried a bunch of other things. I just keep going around in circles.
Here's a simplified version of the function I'm working on:
function make_my_cart_revisions( $cart_obj ) {
if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) ) { return; }
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) { return; }
foreach( $cart_obj->get_cart() as $cart_item) {
// First check to see if the cart item is a subscription product or a variation thereof. Skip any other items.
if ( is_a( $cart_item['data'], 'WC_Product_Subscription' ) || is_a( $cart_item['data'], 'WC_Product_Subscription_Variation' ) ) {
$subscription_trial_length = WC_Subscriptions_Product::get_trial_length( $cart_item['data'] );
$pa_pledge_year = $cart_item['variation']['attribute_pa_pledge_year'];
$pledge_year = substr($pa_pledge_year, 0, 4);
$current_year = date("Y"); // numeric representation of current year, four digits
$billing_period = $cart_item['variation']['attribute_pa_billing_period'];
$pledge_payment_schedule = $cart_item['pledge_payment_schedule']; // Custom product field: "defer-payment" or "pay-immediately"
if ( $pledge_year !== $current_year && $billing_period == 'onetime-payment' && $pledge_payment_schedule == 'pay-immediately' && $subscription_trial_length > 0 ) {
$subscription_trial_length = 0;
// Trying to update the subscription length with the following:
wcs_set_objects_property( $cart_item['data'], 'subscription_trial_length', $subscription_trial_length, 'set_prop_only' );
// Also tried these different approaches to saving the revised trial length:
//$cart_item['data']->update_meta_data( '_subscription_trial_length', $subscription_trial_length );
//$cart_item['data']->set_subscription_trial_length( $subscription_trial_length );
}
} // end check for subscription product/variation
} // end foreach
}
I can see from my debug log that the correct subscription_trial_length is being calculated based on the cart_item details, but all my attempts to save the value so that it shows up correctly in the cart totals have failed. For example, a product for which I've selected the "pay-immediately" option still shows up in the recurring totals but not in the amounts due immediately.
As an alternative, I tried having NO default trial_length and instead setting it to a non-zero amount for products with the deferred payment option (thus eliminating the step of hooking into the woocommerce_subscriptions_product_trial_length
filter), but the problem remained: I can't get the new trial_length value to get set successfully for the cart_item.
Any help will be much appreciated!
来源:https://stackoverflow.com/questions/58037320/woocommerce-subscriptions-set-subscription-trial-length-per-cart-item