Updates to 6.2.0

This commit is contained in:
WooCommerce
2024-04-11 10:13:02 +00:00
parent d3348c6c8f
commit cc9b3f8f53
21 changed files with 358 additions and 233 deletions

View File

@@ -1,5 +1,18 @@
*** Woo Subscriptions Changelog *** *** Woo Subscriptions Changelog ***
2024-04-11 - version 6.2.0
* Add: Declare WooCommerce as a plugin dependency in the plugin header.
* Fix: Ensure next payment dates are only extended when early renewal orders paid via the modal are fully paid. Prevents extending dates on authorized but not captured payments.
* Fix: Updated the switching calculator to handle situations where an upgrade has a new price per day less than the old price per day. Previously this would result in a negative upgrade cost.
* Fix: Update the failing payment method on a subscription when customers successfully pay for a failed renewal order via the block checkout.
* Fix: Resolved an issue that would cause subscriptions to be directly cancelled by the WooCommerce process of automatically cancelling unpaid orders in-line with the hold stock setting.
* Fix: Prevent duplicate status transition notes on subscriptions and potential infinite loops when processing subscription status transitions.
* Fix: Resolved an issue that could lead to "Undefined array key 'order-received'" errors.
* Fix: Resolved errors that could occur when paying for renewal orders via the checkout when the store has custom checkout fields.
* Fix: Resolved database errors that would occur when ordering the subscriptions list table by the 'Last order date' on sites with HPOS enabled.
* Dev: Introduced a new filter ('wcs_setup_cart_for_subscription_initial_payment') to enable third-party plugins to use the pay-for-order flow to complete a subscription's initial payment.
* Dev: Updated subscriptions-core to 7.0.0.
2024-03-28 - version 6.1.0 2024-03-28 - version 6.1.0
* Fix: Ensure the subscription renewal payment process doesn't attempt to reprocess previously paid renewal orders. * Fix: Ensure the subscription renewal payment process doesn't attempt to reprocess previously paid renewal orders.
* Fix: Resolved an issue where discounts, when reapplied to failed or manual subscription order payments, would incorrectly account for inclusive tax. * Fix: Resolved an issue where discounts, when reapplied to failed or manual subscription order payments, would incorrectly account for inclusive tax.

View File

@@ -146,7 +146,11 @@ class WCS_Early_Renewal_Modal_Handler {
wc_add_notice( __( 'Payment for the renewal order was unsuccessful with your payment method on file, please try again.', 'woocommerce-subscriptions' ), 'error' ); wc_add_notice( __( 'Payment for the renewal order was unsuccessful with your payment method on file, please try again.', 'woocommerce-subscriptions' ), 'error' );
wp_redirect( wcs_get_early_renewal_url( $subscription ) ); wp_redirect( wcs_get_early_renewal_url( $subscription ) );
exit(); exit();
} else { }
// Paid early renewals trigger the subscription payment complete hooks, extend next payment dates and reset suspension counts and user roles.
// Orders which are on-hold (manual payment or auth/capture gateways) will be handled when the order eventually is marked as payment complete (process/completed).
if ( $renewal_order->is_paid() ) {
// Trigger the subscription payment complete hooks and reset suspension counts and user roles. // Trigger the subscription payment complete hooks and reset suspension counts and user roles.
$subscription->payment_complete(); $subscription->payment_complete();

View File

@@ -107,6 +107,12 @@ class WCS_Switch_Totals_Calculator {
$this->reset_prorated_price( $switch_item ); $this->reset_prorated_price( $switch_item );
$upgrade_cost = $this->calculate_upgrade_cost( $switch_item ); $upgrade_cost = $this->calculate_upgrade_cost( $switch_item );
// If a negative upgrade cost has been calculated. Have the customer pay a full price minus what they are owed and set the next payment to be the new products first payment date.
if ( $upgrade_cost < 0 ) {
$upgrade_cost = $this->calculate_fully_reduced_upgrade_cost( $cart_item_key, $switch_item );
}
$this->set_upgrade_cost( $switch_item, $upgrade_cost ); $this->set_upgrade_cost( $switch_item, $upgrade_cost );
} }
} }
@@ -514,6 +520,32 @@ class WCS_Switch_Totals_Calculator {
return $this->cart->cart_contents[ $cart_item_key ]['subscription_switch']['first_payment_timestamp']; return $this->cart->cart_contents[ $cart_item_key ]['subscription_switch']['first_payment_timestamp'];
} }
/**
* Calculates the cost of the upgrade when the customer pays the new product's full price minus the amount paid and still owing.
*
* This function is used when a switch results in a negative upgrade cost which typically occurs when stores use the `wcs_switch_proration_switch_type` filter to change the default switch type.
* For example, if a customer is switching from a monthly subscription to a yearly subscription, they will pay the yearly product's full price minus whatever is still owed on the monthly product's price.
*
* eg $20/month switched to a $200 yearly product. The upgrade cost would be 200 - ((20/30) * days-left-in-the-current-billing-term).
* Switching on the first day of the month would result in the following calculation: 200 - ((20/30) * 30) = 200 - 20 = 180. The full $20 is owed.
* Switching halfway through the month would result in the following calculation: 200 - ((20/30) * 15) = 200 - 10 = 190. The customer is owed $10 or half what they paid.
*
* @param string $cart_item_key The switch item's cart item key.
* @param WCS_Switch_Cart_Item $switch_item The switch item.
*
* @return float The upgrade cost.
*/
protected function calculate_fully_reduced_upgrade_cost( $cart_item_key, $switch_item ) {
// When a customer pays the full new product price minus the amount already paid, we need to reduce the prepaid term and the subscription's next payment is 1 billing cycle away.
$this->cart->cart_contents[ $cart_item_key ]['subscription_switch']['first_payment_timestamp'] = WC_Subscriptions_Product::get_first_renewal_payment_time( $switch_item->product );
// The customer is owed whatever they didn't use. If they paid $100 for a monthly subscription and are switching half way through the month, they are owed $50.
$remaining_amount_not_consumed = ( $switch_item->get_total_paid_for_current_period() / $switch_item->get_days_in_old_cycle() ) * $switch_item->get_days_until_next_payment();
// The customer pays the full price of the new product minus the amount they didn't use.
return ( WC_Subscriptions_Product::get_price( $switch_item->product ) * $switch_item->cart_item['quantity'] ) - ( $remaining_amount_not_consumed );
}
/** Helpers */ /** Helpers */
/** /**

View File

@@ -2,16 +2,16 @@
# This file is distributed under the same license as the Woo Subscriptions plugin. # This file is distributed under the same license as the Woo Subscriptions plugin.
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Woo Subscriptions 6.1.0\n" "Project-Id-Version: Woo Subscriptions 6.2.0\n"
"Report-Msgid-Bugs-To: https://woocommerce.com/contact-us\n" "Report-Msgid-Bugs-To: https://woocommerce.com/contact-us\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2024-03-28T06:13:35+00:00\n" "POT-Creation-Date: 2024-04-11T02:40:29+00:00\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"X-Generator: WP-CLI 2.10.0\n" "X-Generator: WP-CLI 2.9.0\n"
"X-Domain: woocommerce-subscriptions\n" "X-Domain: woocommerce-subscriptions\n"
#. Plugin Name of the plugin #. Plugin Name of the plugin
@@ -1368,7 +1368,7 @@ msgstr ""
msgid "Payment for the renewal order was unsuccessful with your payment method on file, please try again." msgid "Payment for the renewal order was unsuccessful with your payment method on file, please try again."
msgstr "" msgstr ""
#: includes/early-renewal/class-wcs-early-renewal-modal-handler.php:154 #: includes/early-renewal/class-wcs-early-renewal-modal-handler.php:158
msgid "Your early renewal order was successful." msgid "Your early renewal order was successful."
msgstr "" msgstr ""
@@ -1385,7 +1385,7 @@ msgstr ""
#. translators: %d: subscription ID. #. translators: %d: subscription ID.
#. translators: placeholder is a subscription ID. #. translators: placeholder is a subscription ID.
#: includes/gateways/class-wc-subscriptions-payment-gateways.php:77 #: includes/gateways/class-wc-subscriptions-payment-gateways.php:77
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:192 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:194
msgid "Subscription doesn't exist in scheduled action: %d" msgid "Subscription doesn't exist in scheduled action: %d"
msgstr "" msgstr ""
@@ -1871,7 +1871,7 @@ msgstr ""
msgid "Invalid switch type \"%s\". Switch must be one of: \"upgrade\", \"downgrade\" or \"crossgrade\"." msgid "Invalid switch type \"%s\". Switch must be one of: \"upgrade\", \"downgrade\" or \"crossgrade\"."
msgstr "" msgstr ""
#: includes/switching/class-wcs-switch-totals-calculator.php:196 #: includes/switching/class-wcs-switch-totals-calculator.php:202
msgid "Your cart contained an invalid subscription switch request. It has been removed from your cart." msgid "Your cart contained an invalid subscription switch request. It has been removed from your cart."
msgstr "" msgstr ""
@@ -1887,46 +1887,6 @@ msgstr ""
msgid "Want to renew early via the checkout? Click %shere.%s" msgid "Want to renew early via the checkout? Click %shere.%s"
msgstr "" msgstr ""
#: tests/unit/scheduler/scheduler.php:65
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:291
msgctxt "table heading"
msgid "Start Date"
msgstr ""
#: tests/unit/scheduler/scheduler.php:66
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:292
msgctxt "table heading"
msgid "Trial End"
msgstr ""
#: tests/unit/scheduler/scheduler.php:67
#: vendor/woocommerce/subscriptions-core/templates/myaccount/my-subscriptions.php:40
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:293
msgctxt "table heading"
msgid "Next Payment"
msgstr ""
#: tests/unit/scheduler/scheduler.php:68
#: vendor/woocommerce/subscriptions-core/templates/emails/cancelled-subscription.php:23
#: vendor/woocommerce/subscriptions-core/templates/emails/expired-subscription.php:23
#: vendor/woocommerce/subscriptions-core/templates/emails/on-hold-subscription.php:23
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:294
msgctxt "table heading"
msgid "Last Order Date"
msgstr ""
#: tests/unit/scheduler/scheduler.php:69
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:295
msgctxt "table heading"
msgid "Cancelled Date"
msgstr ""
#: tests/unit/scheduler/scheduler.php:70
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:296
msgctxt "table heading"
msgid "End Date"
msgstr ""
#. translators: 1: relation type, 2: list of valid relation types. #. translators: 1: relation type, 2: list of valid relation types.
#: vendor/woocommerce/subscriptions-core/includes/abstracts/abstract-wcs-related-order-store.php:148 #: vendor/woocommerce/subscriptions-core/includes/abstracts/abstract-wcs-related-order-store.php:148
msgid "Invalid relation type: %1$s. Order relationship type must be one of: %2$s." msgid "Invalid relation type: %1$s. Order relationship type must be one of: %2$s."
@@ -2408,7 +2368,7 @@ msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-post-types.php:327 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-post-types.php:327
#: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-post-types.php:1365 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-post-types.php:1365
#: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-post-types.php:1754 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-post-types.php:1754
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1937 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1955
#: vendor/woocommerce/subscriptions-core/includes/wcs-user-functions.php:329 #: vendor/woocommerce/subscriptions-core/includes/wcs-user-functions.php:329
#: vendor/woocommerce/subscriptions-core/templates/myaccount/related-orders.php:78 #: vendor/woocommerce/subscriptions-core/templates/myaccount/related-orders.php:78
msgctxt "an action on a subscription" msgctxt "an action on a subscription"
@@ -2532,7 +2492,7 @@ msgstr[1] ""
#. translators: placeholder is the display name of a payment gateway a subscription was paid by #. translators: placeholder is the display name of a payment gateway a subscription was paid by
#. translators: %s: payment method. #. translators: %s: payment method.
#: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-post-types.php:645 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-post-types.php:645
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2126 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2147
msgid "Via %s" msgid "Via %s"
msgstr "" msgstr ""
@@ -2600,7 +2560,7 @@ msgid "None"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-post-types.php:1159 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-post-types.php:1159
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2108 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2129
#: vendor/woocommerce/subscriptions-core/includes/class-wcs-change-payment-method-admin.php:170 #: vendor/woocommerce/subscriptions-core/includes/class-wcs-change-payment-method-admin.php:170
msgid "Manual Renewal" msgid "Manual Renewal"
msgstr "" msgstr ""
@@ -2955,139 +2915,139 @@ msgid "Read more"
msgstr "" msgstr ""
#. translators: %s: subscription status. #. translators: %s: subscription status.
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:425 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:437
msgid "Unable to change subscription status to \"%s\"." msgid "Unable to change subscription status to \"%s\"."
msgstr "" msgstr ""
#. translators: 1: subscription status, 2: error message. #. translators: 1: subscription status, 2: error message.
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:548 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:560
msgid "Unable to change subscription status to \"%1$s\". Exception: %2$s" msgid "Unable to change subscription status to \"%1$s\". Exception: %2$s"
msgstr "" msgstr ""
#. translators: 1: old subscription status 2: new subscription status #. translators: 1: old subscription status 2: new subscription status
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:578 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:593
msgid "Status changed from %1$s to %2$s." msgid "Status changed from %1$s to %2$s."
msgstr "" msgstr ""
#. translators: %s: new order status #. translators: %s: new order status
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:592 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:607
msgid "Status set to %s." msgid "Status set to %s."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:606 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:621
msgid "Error during subscription status transition." msgid "Error during subscription status transition."
msgstr "" msgstr ""
#. translators: placeholder is human time diff (e.g. "3 weeks") #. translators: placeholder is human time diff (e.g. "3 weeks")
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1296 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1308
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2387 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2405
msgid "In %s" msgid "In %s"
msgstr "" msgstr ""
#. translators: placeholder is human time diff (e.g. "3 weeks") #. translators: placeholder is human time diff (e.g. "3 weeks")
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1299 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1311
#: vendor/woocommerce/subscriptions-core/includes/wcs-formatting-functions.php:246 #: vendor/woocommerce/subscriptions-core/includes/wcs-formatting-functions.php:246
msgid "%s ago" msgid "%s ago"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1306 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1318
msgid "Not yet ended" msgid "Not yet ended"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1309 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1321
msgid "Not cancelled" msgid "Not cancelled"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1314 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1326
msgctxt "original denotes there is no date to display" msgctxt "original denotes there is no date to display"
msgid "-" msgid "-"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1422 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1434
msgid "The creation date of a subscription can not be deleted, only updated." msgid "The creation date of a subscription can not be deleted, only updated."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1425 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1437
msgid "The start date of a subscription can not be deleted, only updated." msgid "The start date of a subscription can not be deleted, only updated."
msgstr "" msgstr ""
#. translators: %s: date type (e.g. "trial_end"). #. translators: %s: date type (e.g. "trial_end").
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1430 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1442
msgid "The %s date of a subscription can not be deleted. You must delete the order." msgid "The %s date of a subscription can not be deleted. You must delete the order."
msgstr "" msgstr ""
#. translators: %d: subscription ID. #. translators: %d: subscription ID.
#. translators: %d: order ID. #. translators: %d: order ID.
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1439 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1451
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2549 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2570
msgid "Subscription #%d: " msgid "Subscription #%d: "
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1853 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1865
msgid "Payment status marked complete." msgid "Payment status marked complete."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1886 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1907
msgid "Payment failed." msgid "Payment failed."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1891 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:1912
msgid "Subscription Cancelled: maximum number of failed payments reached." msgid "Subscription Cancelled: maximum number of failed payments reached."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2001 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2022
msgid "The \"all\" value for $order_type parameter is deprecated. It was a misnomer, as it did not return resubscribe orders. It was also inconsistent with order type values accepted by wcs_get_subscription_orders(). Use array( \"parent\", \"renewal\", \"switch\" ) to maintain previous behaviour, or \"any\" to receive all order types, including switch and resubscribe." msgid "The \"all\" value for $order_type parameter is deprecated. It was a misnomer, as it did not return resubscribe orders. It was also inconsistent with order type values accepted by wcs_get_subscription_orders(). Use array( \"parent\", \"renewal\", \"switch\" ) to maintain previous behaviour, or \"any\" to receive all order types, including switch and resubscribe."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2205 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2226
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:835 #: vendor/woocommerce/subscriptions-core/wcs-functions.php:835
msgid "Payment method meta must be an array." msgid "Payment method meta must be an array."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2441 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2462
msgid "Invalid format. First parameter needs to be an array." msgid "Invalid format. First parameter needs to be an array."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2445 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2466
msgid "Invalid data. First parameter was empty when passed to update_dates()." msgid "Invalid data. First parameter was empty when passed to update_dates()."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2452 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2473
msgid "Invalid data. First parameter has a date that is not in the registered date types." msgid "Invalid data. First parameter has a date that is not in the registered date types."
msgstr "" msgstr ""
#. translators: placeholder is date type (e.g. "end", "next_payment"...) #. translators: placeholder is date type (e.g. "end", "next_payment"...)
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2479 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2500
msgctxt "appears in an error message if date is wrong format" msgctxt "appears in an error message if date is wrong format"
msgid "Invalid %s date. The date must be of the format: \"Y-m-d H:i:s\"." msgid "Invalid %s date. The date must be of the format: \"Y-m-d H:i:s\"."
msgstr "" msgstr ""
#. translators: %s: date type (e.g. "end"). #. translators: %s: date type (e.g. "end").
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2517 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2538
msgid "The %s date must occur after the cancellation date." msgid "The %s date must occur after the cancellation date."
msgstr "" msgstr ""
#. translators: %s: date type (e.g. "end"). #. translators: %s: date type (e.g. "end").
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2523 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2544
msgid "The %s date must occur after the last payment date." msgid "The %s date must occur after the last payment date."
msgstr "" msgstr ""
#. translators: %s: date type (e.g. "end"). #. translators: %s: date type (e.g. "end").
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2528 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2549
msgid "The %s date must occur after the next payment date." msgid "The %s date must occur after the next payment date."
msgstr "" msgstr ""
#. translators: %s: date type (e.g. "end"). #. translators: %s: date type (e.g. "end").
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2534 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2555
msgid "The %s date must occur after the trial end date." msgid "The %s date must occur after the trial end date."
msgstr "" msgstr ""
#. translators: %s: date type (e.g. "next_payment"). #. translators: %s: date type (e.g. "next_payment").
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2539 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2560
msgid "The %s date must occur after the start date." msgid "The %s date must occur after the start date."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2569 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2590
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-checkout.php:348 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-checkout.php:348
msgid "Backordered" msgid "Backordered"
msgstr "" msgstr ""
@@ -3699,145 +3659,145 @@ msgstr ""
msgid "Would you like to add a payment method now?" msgid "Would you like to add a payment method now?"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:112 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:114
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2001
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2019 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2019
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2037
msgctxt "used in order note as reason for why subscription status changed" msgctxt "used in order note as reason for why subscription status changed"
msgid "Subscription renewal payment due:" msgid "Subscription renewal payment due:"
msgstr "" msgstr ""
#. translators: placeholder %1 is an order note. %2 is the error message that was thrown. #. translators: placeholder %1 is an order note. %2 is the error message that was thrown.
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:149 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:151
msgid "Error: Unable to create renewal order with note \"%1$s\". Message: %2$s" msgid "Error: Unable to create renewal order with note \"%1$s\". Message: %2$s"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:159 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:161
msgid "Manual renewal order awaiting customer payment." msgid "Manual renewal order awaiting customer payment."
msgstr "" msgstr ""
#. translators: $1: order number, $2: error message #. translators: $1: order number, $2: error message
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:342 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:344
msgid "Failed to activate subscription status for order #%1$s: %2$s" msgid "Failed to activate subscription status for order #%1$s: %2$s"
msgstr "" msgstr ""
#. translators: $1: order number, $2: error message #. translators: $1: order number, $2: error message
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:370 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:372
msgid "Failed to update subscription status after order #%1$s was put on-hold: %2$s" msgid "Failed to update subscription status after order #%1$s was put on-hold: %2$s"
msgstr "" msgstr ""
#. translators: $1: order number, $2: error message #. translators: $1: order number, $2: error message
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:398 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:400
msgid "Failed to cancel subscription after order #%1$s was cancelled: %2$s" msgid "Failed to cancel subscription after order #%1$s was cancelled: %2$s"
msgstr "" msgstr ""
#. translators: $1: order number, $2: error message #. translators: $1: order number, $2: error message
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:426 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:428
msgid "Failed to set subscription as expired for order #%1$s: %2$s" msgid "Failed to set subscription as expired for order #%1$s: %2$s"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:452 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:454
msgid "Subscription sign up failed." msgid "Subscription sign up failed."
msgstr "" msgstr ""
#. translators: $1: order number, $2: error message #. translators: $1: order number, $2: error message
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:462 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:464
msgid "Failed to process failed payment on subscription for order #%1$s: %2$s" msgid "Failed to process failed payment on subscription for order #%1$s: %2$s"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:536 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:538
msgid "Error: Unable to create subscription. Please try again." msgid "Error: Unable to create subscription. Please try again."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:558 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:560
msgid "Error: Unable to add product to created subscription. Please try again." msgid "Error: Unable to add product to created subscription. Please try again."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:603 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:605
msgid "Pending subscription created." msgid "Pending subscription created."
msgstr "" msgstr ""
#. Translators: 1: The subscription ID number. 2: The current user's username. #. Translators: 1: The subscription ID number. 2: The current user's username.
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:997 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1015
msgid "The related subscription #%1$s has been deleted after the customer was deleted by %2$s." msgid "The related subscription #%1$s has been deleted after the customer was deleted by %2$s."
msgstr "" msgstr ""
#. Translators: Placeholder is the subscription ID number. #. Translators: Placeholder is the subscription ID number.
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1000 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1018
msgid "The related subscription #%s has been deleted after the customer was deleted." msgid "The related subscription #%s has been deleted after the customer was deleted."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1146 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1164
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:221 #: vendor/woocommerce/subscriptions-core/wcs-functions.php:221
msgctxt "Subscription status" msgctxt "Subscription status"
msgid "Active" msgid "Active"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1149 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1167
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:223 #: vendor/woocommerce/subscriptions-core/wcs-functions.php:223
msgctxt "Subscription status" msgctxt "Subscription status"
msgid "Cancelled" msgid "Cancelled"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1152 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1170
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:225 #: vendor/woocommerce/subscriptions-core/wcs-functions.php:225
msgctxt "Subscription status" msgctxt "Subscription status"
msgid "Expired" msgid "Expired"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1155 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1173
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:220 #: vendor/woocommerce/subscriptions-core/wcs-functions.php:220
msgctxt "Subscription status" msgctxt "Subscription status"
msgid "Pending" msgid "Pending"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1158 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1176
msgctxt "Subscription status" msgctxt "Subscription status"
msgid "Failed" msgid "Failed"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1162 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1180
msgctxt "Subscription status" msgctxt "Subscription status"
msgid "On-hold" msgid "On-hold"
msgstr "" msgstr ""
#. translators: 1$: month number (e.g. "01"), 2$: month abbreviation (e.g. "Jan") #. translators: 1$: month number (e.g. "01"), 2$: month abbreviation (e.g. "Jan")
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1914 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1932
msgctxt "used in a select box" msgctxt "used in a select box"
msgid "%1$s-%2$s" msgid "%1$s-%2$s"
msgstr "" msgstr ""
#. translators: all fields are full html nodes: 1$: month input, 2$: day input, 3$: year input, 4$: hour input, 5$: minute input. Change the order if you'd like #. translators: all fields are full html nodes: 1$: month input, 2$: day input, 3$: year input, 4$: hour input, 5$: minute input. Change the order if you'd like
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1927 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1945
msgid "%1$s%2$s, %3$s @ %4$s : %5$s" msgid "%1$s%2$s, %3$s @ %4$s : %5$s"
msgstr "" msgstr ""
#. translators: all fields are full html nodes: 1$: month input, 2$: day input, 3$: year input. Change the order if you'd like #. translators: all fields are full html nodes: 1$: month input, 2$: day input, 3$: year input. Change the order if you'd like
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1931 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1949
msgid "%1$s%2$s, %3$s" msgid "%1$s%2$s, %3$s"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1936 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:1954
msgid "Change" msgid "Change"
msgstr "" msgstr ""
#. translators: placeholder is subscription ID #. translators: placeholder is subscription ID
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2269 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2287
msgid "Failed sign-up for subscription %s." msgid "Failed sign-up for subscription %s."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2360 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2378
msgid "Invalid security token, please reload the page and try again." msgid "Invalid security token, please reload the page and try again."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2364 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2382
msgid "Only store managers can edit payment dates." msgid "Only store managers can edit payment dates."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2368 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2386
msgid "Please enter all date fields." msgid "Please enter all date fields."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2393 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php:2411
msgid "Date Changed" msgid "Date Changed"
msgstr "" msgstr ""
@@ -4137,7 +4097,7 @@ msgstr ""
msgid "Weekly" msgid "Weekly"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wcs-cart-initial-payment.php:65 #: vendor/woocommerce/subscriptions-core/includes/class-wcs-cart-initial-payment.php:85
#: vendor/woocommerce/subscriptions-core/includes/class-wcs-cart-renewal.php:199 #: vendor/woocommerce/subscriptions-core/includes/class-wcs-cart-renewal.php:199
msgid "That doesn't appear to be your order." msgid "That doesn't appear to be your order."
msgstr "" msgstr ""
@@ -4177,16 +4137,16 @@ msgid_plural "We couldn't find the original renewal orders for items in your car
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: vendor/woocommerce/subscriptions-core/includes/class-wcs-cart-renewal.php:687 #: vendor/woocommerce/subscriptions-core/includes/class-wcs-cart-renewal.php:698
msgid "All linked subscription items have been removed from the cart." msgid "All linked subscription items have been removed from the cart."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wcs-cart-renewal.php:716 #: vendor/woocommerce/subscriptions-core/includes/class-wcs-cart-renewal.php:727
msgctxt "Used in WooCommerce by removed item notification: \"_All linked subscription items were_ removed. Undo?\" Filter for item title." msgctxt "Used in WooCommerce by removed item notification: \"_All linked subscription items were_ removed. Undo?\" Filter for item title."
msgid "All linked subscription items were" msgid "All linked subscription items were"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/includes/class-wcs-cart-renewal.php:1532 #: vendor/woocommerce/subscriptions-core/includes/class-wcs-cart-renewal.php:1543
msgctxt "The place order button text while renewing a subscription" msgctxt "The place order button text while renewing a subscription"
msgid "Renew subscription" msgid "Renew subscription"
msgstr "" msgstr ""
@@ -6407,6 +6367,14 @@ msgctxt "table headings in notification email"
msgid "Price" msgid "Price"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/templates/emails/cancelled-subscription.php:23
#: vendor/woocommerce/subscriptions-core/templates/emails/expired-subscription.php:23
#: vendor/woocommerce/subscriptions-core/templates/emails/on-hold-subscription.php:23
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:294
msgctxt "table heading"
msgid "Last Order Date"
msgstr ""
#: vendor/woocommerce/subscriptions-core/templates/emails/cancelled-subscription.php:24 #: vendor/woocommerce/subscriptions-core/templates/emails/cancelled-subscription.php:24
msgctxt "table headings in notification email" msgctxt "table headings in notification email"
msgid "End of Prepaid Term" msgid "End of Prepaid Term"
@@ -6689,6 +6657,12 @@ msgstr ""
msgid "ID" msgid "ID"
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/templates/myaccount/my-subscriptions.php:40
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:293
msgctxt "table heading"
msgid "Next Payment"
msgstr ""
#: vendor/woocommerce/subscriptions-core/templates/myaccount/my-subscriptions.php:46 #: vendor/woocommerce/subscriptions-core/templates/myaccount/my-subscriptions.php:46
#: vendor/woocommerce/subscriptions-core/templates/myaccount/related-orders.php:53 #: vendor/woocommerce/subscriptions-core/templates/myaccount/related-orders.php:53
#: vendor/woocommerce/subscriptions-core/templates/myaccount/related-subscriptions.php:42 #: vendor/woocommerce/subscriptions-core/templates/myaccount/related-subscriptions.php:42
@@ -6868,6 +6842,26 @@ msgstr ""
msgid "Can not get address type display name. Address type is not a string." msgid "Can not get address type display name. Address type is not a string."
msgstr "" msgstr ""
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:291
msgctxt "table heading"
msgid "Start Date"
msgstr ""
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:292
msgctxt "table heading"
msgid "Trial End"
msgstr ""
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:295
msgctxt "table heading"
msgid "Cancelled Date"
msgstr ""
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:296
msgctxt "table heading"
msgid "End Date"
msgstr ""
#: vendor/woocommerce/subscriptions-core/wcs-functions.php:331 #: vendor/woocommerce/subscriptions-core/wcs-functions.php:331
msgid "Date type is not a string." msgid "Date type is not a string."
msgstr "" msgstr ""

2
vendor/autoload.php vendored
View File

@@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php'; require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInite5f25043b4323431d48e7e46b04aa2c9::getLoader(); return ComposerAutoloaderInit270a670e4e35541a06419730c5cc18f6::getLoader();

View File

@@ -45,34 +45,35 @@ class ClassLoader
/** @var \Closure(string):void */ /** @var \Closure(string):void */
private static $includeFile; private static $includeFile;
/** @var string|null */ /** @var ?string */
private $vendorDir; private $vendorDir;
// PSR-4 // PSR-4
/** /**
* @var array<string, array<string, int>> * @var array[]
* @psalm-var array<string, array<string, int>>
*/ */
private $prefixLengthsPsr4 = array(); private $prefixLengthsPsr4 = array();
/** /**
* @var array<string, list<string>> * @var array[]
* @psalm-var array<string, array<int, string>>
*/ */
private $prefixDirsPsr4 = array(); private $prefixDirsPsr4 = array();
/** /**
* @var list<string> * @var array[]
* @psalm-var array<string, string>
*/ */
private $fallbackDirsPsr4 = array(); private $fallbackDirsPsr4 = array();
// PSR-0 // PSR-0
/** /**
* List of PSR-0 prefixes * @var array[]
* * @psalm-var array<string, array<string, string[]>>
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/ */
private $prefixesPsr0 = array(); private $prefixesPsr0 = array();
/** /**
* @var list<string> * @var array[]
* @psalm-var array<string, string>
*/ */
private $fallbackDirsPsr0 = array(); private $fallbackDirsPsr0 = array();
@@ -80,7 +81,8 @@ class ClassLoader
private $useIncludePath = false; private $useIncludePath = false;
/** /**
* @var array<string, string> * @var string[]
* @psalm-var array<string, string>
*/ */
private $classMap = array(); private $classMap = array();
@@ -88,20 +90,21 @@ class ClassLoader
private $classMapAuthoritative = false; private $classMapAuthoritative = false;
/** /**
* @var array<string, bool> * @var bool[]
* @psalm-var array<string, bool>
*/ */
private $missingClasses = array(); private $missingClasses = array();
/** @var string|null */ /** @var ?string */
private $apcuPrefix; private $apcuPrefix;
/** /**
* @var array<string, self> * @var self[]
*/ */
private static $registeredLoaders = array(); private static $registeredLoaders = array();
/** /**
* @param string|null $vendorDir * @param ?string $vendorDir
*/ */
public function __construct($vendorDir = null) public function __construct($vendorDir = null)
{ {
@@ -110,7 +113,7 @@ class ClassLoader
} }
/** /**
* @return array<string, list<string>> * @return string[]
*/ */
public function getPrefixes() public function getPrefixes()
{ {
@@ -122,7 +125,8 @@ class ClassLoader
} }
/** /**
* @return array<string, list<string>> * @return array[]
* @psalm-return array<string, array<int, string>>
*/ */
public function getPrefixesPsr4() public function getPrefixesPsr4()
{ {
@@ -130,7 +134,8 @@ class ClassLoader
} }
/** /**
* @return list<string> * @return array[]
* @psalm-return array<string, string>
*/ */
public function getFallbackDirs() public function getFallbackDirs()
{ {
@@ -138,7 +143,8 @@ class ClassLoader
} }
/** /**
* @return list<string> * @return array[]
* @psalm-return array<string, string>
*/ */
public function getFallbackDirsPsr4() public function getFallbackDirsPsr4()
{ {
@@ -146,7 +152,8 @@ class ClassLoader
} }
/** /**
* @return array<string, string> Array of classname => path * @return string[] Array of classname => path
* @psalm-return array<string, string>
*/ */
public function getClassMap() public function getClassMap()
{ {
@@ -154,7 +161,8 @@ class ClassLoader
} }
/** /**
* @param array<string, string> $classMap Class to filename map * @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
* *
* @return void * @return void
*/ */
@@ -171,25 +179,24 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, either * Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix. * appending or prepending to the ones previously set for this prefix.
* *
* @param string $prefix The prefix * @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories * @param string[]|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories * @param bool $prepend Whether to prepend the directories
* *
* @return void * @return void
*/ */
public function add($prefix, $paths, $prepend = false) public function add($prefix, $paths, $prepend = false)
{ {
$paths = (array) $paths;
if (!$prefix) { if (!$prefix) {
if ($prepend) { if ($prepend) {
$this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0 = array_merge(
$paths, (array) $paths,
$this->fallbackDirsPsr0 $this->fallbackDirsPsr0
); );
} else { } else {
$this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0, $this->fallbackDirsPsr0,
$paths (array) $paths
); );
} }
@@ -198,19 +205,19 @@ class ClassLoader
$first = $prefix[0]; $first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) { if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = $paths; $this->prefixesPsr0[$first][$prefix] = (array) $paths;
return; return;
} }
if ($prepend) { if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix] = array_merge(
$paths, (array) $paths,
$this->prefixesPsr0[$first][$prefix] $this->prefixesPsr0[$first][$prefix]
); );
} else { } else {
$this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix], $this->prefixesPsr0[$first][$prefix],
$paths (array) $paths
); );
} }
} }
@@ -219,9 +226,9 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, either * Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace. * appending or prepending to the ones previously set for this namespace.
* *
* @param string $prefix The prefix/namespace, with trailing '\\' * @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories * @param string[]|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories * @param bool $prepend Whether to prepend the directories
* *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* *
@@ -229,18 +236,17 @@ class ClassLoader
*/ */
public function addPsr4($prefix, $paths, $prepend = false) public function addPsr4($prefix, $paths, $prepend = false)
{ {
$paths = (array) $paths;
if (!$prefix) { if (!$prefix) {
// Register directories for the root namespace. // Register directories for the root namespace.
if ($prepend) { if ($prepend) {
$this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4 = array_merge(
$paths, (array) $paths,
$this->fallbackDirsPsr4 $this->fallbackDirsPsr4
); );
} else { } else {
$this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4, $this->fallbackDirsPsr4,
$paths (array) $paths
); );
} }
} elseif (!isset($this->prefixDirsPsr4[$prefix])) { } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
@@ -250,18 +256,18 @@ class ClassLoader
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
} }
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = $paths; $this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) { } elseif ($prepend) {
// Prepend directories for an already registered namespace. // Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix] = array_merge(
$paths, (array) $paths,
$this->prefixDirsPsr4[$prefix] $this->prefixDirsPsr4[$prefix]
); );
} else { } else {
// Append directories for an already registered namespace. // Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix], $this->prefixDirsPsr4[$prefix],
$paths (array) $paths
); );
} }
} }
@@ -270,8 +276,8 @@ class ClassLoader
* Registers a set of PSR-0 directories for a given prefix, * Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix. * replacing any others previously set for this prefix.
* *
* @param string $prefix The prefix * @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories * @param string[]|string $paths The PSR-0 base directories
* *
* @return void * @return void
*/ */
@@ -288,8 +294,8 @@ class ClassLoader
* Registers a set of PSR-4 directories for a given namespace, * Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace. * replacing any others previously set for this namespace.
* *
* @param string $prefix The prefix/namespace, with trailing '\\' * @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories * @param string[]|string $paths The PSR-4 base directories
* *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* *
@@ -475,9 +481,9 @@ class ClassLoader
} }
/** /**
* Returns the currently registered loaders keyed by their corresponding vendor directories. * Returns the currently registered loaders indexed by their corresponding vendor directories.
* *
* @return array<string, self> * @return self[]
*/ */
public static function getRegisteredLoaders() public static function getRegisteredLoaders()
{ {

View File

@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer // autoload_real.php @generated by Composer
class ComposerAutoloaderInite5f25043b4323431d48e7e46b04aa2c9 class ComposerAutoloaderInit270a670e4e35541a06419730c5cc18f6
{ {
private static $loader; private static $loader;
@@ -24,12 +24,12 @@ class ComposerAutoloaderInite5f25043b4323431d48e7e46b04aa2c9
require __DIR__ . '/platform_check.php'; require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInite5f25043b4323431d48e7e46b04aa2c9', 'loadClassLoader'), true, true); spl_autoload_register(array('ComposerAutoloaderInit270a670e4e35541a06419730c5cc18f6', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInite5f25043b4323431d48e7e46b04aa2c9', 'loadClassLoader')); spl_autoload_unregister(array('ComposerAutoloaderInit270a670e4e35541a06419730c5cc18f6', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php'; require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInite5f25043b4323431d48e7e46b04aa2c9::getInitializer($loader)); call_user_func(\Composer\Autoload\ComposerStaticInit270a670e4e35541a06419730c5cc18f6::getInitializer($loader));
$loader->register(true); $loader->register(true);

View File

@@ -4,7 +4,7 @@
namespace Composer\Autoload; namespace Composer\Autoload;
class ComposerStaticInite5f25043b4323431d48e7e46b04aa2c9 class ComposerStaticInit270a670e4e35541a06419730c5cc18f6
{ {
public static $prefixLengthsPsr4 = array ( public static $prefixLengthsPsr4 = array (
'C' => 'C' =>
@@ -129,9 +129,9 @@ class ComposerStaticInite5f25043b4323431d48e7e46b04aa2c9
public static function getInitializer(ClassLoader $loader) public static function getInitializer(ClassLoader $loader)
{ {
return \Closure::bind(function () use ($loader) { return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInite5f25043b4323431d48e7e46b04aa2c9::$prefixLengthsPsr4; $loader->prefixLengthsPsr4 = ComposerStaticInit270a670e4e35541a06419730c5cc18f6::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInite5f25043b4323431d48e7e46b04aa2c9::$prefixDirsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit270a670e4e35541a06419730c5cc18f6::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInite5f25043b4323431d48e7e46b04aa2c9::$classMap; $loader->classMap = ComposerStaticInit270a670e4e35541a06419730c5cc18f6::$classMap;
}, null, ClassLoader::class); }, null, ClassLoader::class);
} }

View File

@@ -156,17 +156,17 @@
}, },
{ {
"name": "woocommerce/subscriptions-core", "name": "woocommerce/subscriptions-core",
"version": "6.9.0", "version": "7.0.0",
"version_normalized": "6.9.0.0", "version_normalized": "7.0.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Automattic/woocommerce-subscriptions-core.git", "url": "https://github.com/Automattic/woocommerce-subscriptions-core.git",
"reference": "baf73669ba923b544aec87421282b753e277171f" "reference": "80a6cff950b4d43932382ebda2bad801b35af229"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Automattic/woocommerce-subscriptions-core/zipball/baf73669ba923b544aec87421282b753e277171f", "url": "https://api.github.com/repos/Automattic/woocommerce-subscriptions-core/zipball/80a6cff950b4d43932382ebda2bad801b35af229",
"reference": "baf73669ba923b544aec87421282b753e277171f", "reference": "80a6cff950b4d43932382ebda2bad801b35af229",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -179,7 +179,7 @@
"woocommerce/woocommerce-sniffs": "0.1.0", "woocommerce/woocommerce-sniffs": "0.1.0",
"yoast/phpunit-polyfills": "1.1.0" "yoast/phpunit-polyfills": "1.1.0"
}, },
"time": "2024-03-28T05:12:56+00:00", "time": "2024-04-11T01:44:20+00:00",
"type": "wordpress-plugin", "type": "wordpress-plugin",
"extra": { "extra": {
"phpcodesniffer-search-depth": 2 "phpcodesniffer-search-depth": 2
@@ -209,7 +209,7 @@
"description": "Sell products and services with recurring payments in your WooCommerce Store.", "description": "Sell products and services with recurring payments in your WooCommerce Store.",
"homepage": "https://github.com/Automattic/woocommerce-subscriptions-core", "homepage": "https://github.com/Automattic/woocommerce-subscriptions-core",
"support": { "support": {
"source": "https://github.com/Automattic/woocommerce-subscriptions-core/tree/6.9.0", "source": "https://github.com/Automattic/woocommerce-subscriptions-core/tree/7.0.0",
"issues": "https://github.com/Automattic/woocommerce-subscriptions-core/issues" "issues": "https://github.com/Automattic/woocommerce-subscriptions-core/issues"
}, },
"install-path": "../woocommerce/subscriptions-core" "install-path": "../woocommerce/subscriptions-core"

View File

@@ -1,9 +1,9 @@
<?php return array( <?php return array(
'root' => array( 'root' => array(
'name' => 'woocommerce/woocommerce-subscriptions', 'name' => 'woocommerce/woocommerce-subscriptions',
'pretty_version' => 'dev-release/6.1.0', 'pretty_version' => 'dev-release/6.2.0',
'version' => 'dev-release/6.1.0', 'version' => 'dev-release/6.2.0',
'reference' => 'a609ac6f082f5fff09d0059eebcc48aa11229f58', 'reference' => '6c5d3d921f40709889b3f583726869f2fa95877f',
'type' => 'wordpress-plugin', 'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@@ -32,18 +32,18 @@
), ),
), ),
'woocommerce/subscriptions-core' => array( 'woocommerce/subscriptions-core' => array(
'pretty_version' => '6.9.0', 'pretty_version' => '7.0.0',
'version' => '6.9.0.0', 'version' => '7.0.0.0',
'reference' => 'baf73669ba923b544aec87421282b753e277171f', 'reference' => '80a6cff950b4d43932382ebda2bad801b35af229',
'type' => 'wordpress-plugin', 'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../woocommerce/subscriptions-core', 'install_path' => __DIR__ . '/../woocommerce/subscriptions-core',
'aliases' => array(), 'aliases' => array(),
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'woocommerce/woocommerce-subscriptions' => array( 'woocommerce/woocommerce-subscriptions' => array(
'pretty_version' => 'dev-release/6.1.0', 'pretty_version' => 'dev-release/6.2.0',
'version' => 'dev-release/6.1.0', 'version' => 'dev-release/6.2.0',
'reference' => 'a609ac6f082f5fff09d0059eebcc48aa11229f58', 'reference' => '6c5d3d921f40709889b3f583726869f2fa95877f',
'type' => 'wordpress-plugin', 'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),

View File

@@ -1,5 +1,14 @@
*** WooCommerce Subscriptions Core Changelog *** *** WooCommerce Subscriptions Core Changelog ***
= 7.0.0 - 2024-04-11 =
* Fix - Update the failing payment method on a subscription when customers successfully pay for a failed renewal order via the block checkout.
* Fix - Resolved an issue that would cause subscriptions to be directly cancelled by the WooCommerce process of automatically cancelling unpaid orders in-line with the hold stock setting.
* Fix - Prevent duplicate status transition notes on subscriptions and potential infinite loops when processing subscription status transitions.
* Fix - Resolved an issue that could lead to "Undefined array key 'order-received'" errors.
* Fix - Resolved errors that could occur when paying for renewal orders via the checkout when the store has custom checkout fields.
* Fix - Resolved database errors that would occur when ordering the subscriptions list table by the 'Last order date' on sites with HPOS enabled.
* Dev - Introduced a new filter ('wcs_setup_cart_for_subscription_initial_payment') to enable third-party plugins to use the pay-for-order flow to complete a subscription's initial payment.
= 6.9.0 - 2024-03-28 = = 6.9.0 - 2024-03-28 =
* Fix - Resolved an issue where discounts, when reapplied to failed or manual subscription order payments, would incorrectly account for inclusive tax. * Fix - Resolved an issue where discounts, when reapplied to failed or manual subscription order payments, would incorrectly account for inclusive tax.
* Fix - Resolved an issue that could cause an empty error notice to appear on the My Account > Payment methods page when a customer attempted to delete a token used by subscriptions. * Fix - Resolved an issue that could cause an empty error notice to appear on the My Account > Payment methods page when a customer attempted to delete a token used by subscriptions.

View File

@@ -1811,9 +1811,7 @@ class WCS_Admin_Post_Types {
$query_order = strtoupper( $args['order'] ); $query_order = strtoupper( $args['order'] );
// fields and order are identical in both cases $pieces['orderby'] = "COALESCE(lp.last_payment, parent_order.date_created_gmt, 0) {$query_order}";
$pieces['fields'] .= ', COALESCE(lp.last_payment, orders.date_created_gmt, 0) as lp';
$pieces['orderby'] = "CAST(lp AS DATETIME) {$query_order}";
return $pieces; return $pieces;
} }
@@ -1841,7 +1839,7 @@ class WCS_Admin_Post_Types {
WHERE order_meta.meta_key = '_subscription_renewal' WHERE order_meta.meta_key = '_subscription_renewal'
GROUP BY order_meta.meta_value) lp GROUP BY order_meta.meta_value) lp
ON {$order_table}.id = lp.meta_value ON {$order_table}.id = lp.meta_value
LEFT JOIN {$order_table} orders on {$order_table}.parent_order_id = orders.ID"; LEFT JOIN {$order_table} as parent_order on {$order_table}.parent_order_id = parent_order.ID";
return $pieces; return $pieces;
} }
@@ -1866,24 +1864,22 @@ class WCS_Admin_Post_Types {
$table_name = substr( "{$wpdb->prefix}tmp_{$session}_lastpayment", 0, 64 ); $table_name = substr( "{$wpdb->prefix}tmp_{$session}_lastpayment", 0, 64 );
// Create a temporary table, drop the previous one. // Create a temporary table, drop the previous one.
$wpdb->query( $wpdb->prepare( 'DROP TEMPORARY TABLE IF EXISTS %s', $table_name ) ); //phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$wpdb->query( "DROP TEMPORARY TABLE IF EXISTS {$table_name}" );
$wpdb->query( $wpdb->query(
$wpdb->prepare( "CREATE TEMPORARY TABLE {$table_name} (id INT PRIMARY KEY, last_payment DATETIME) AS
"CREATE TEMPORARY TABLE %s (id INT PRIMARY KEY, last_payment DATETIME) AS SELECT order_meta.meta_value as id, MAX( orders.date_created_gmt ) as last_payment
SELECT order_meta.meta_value as id, MAX( orders.date_created_gmt ) as last_payment FROM %s order_meta FROM {$meta_table} as order_meta
LEFT JOIN %s as orders ON orders.id = order_meta.order_id LEFT JOIN {$order_table} as orders ON orders.id = order_meta.order_id
WHERE order_meta.meta_key = '_subscription_renewal' WHERE order_meta.meta_key = '_subscription_renewal'
GROUP BY order_meta.meta_value", GROUP BY order_meta.meta_value"
$table_name,
$meta_table,
$order_table
)
); );
//phpcs:enable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$pieces['join'] .= "LEFT JOIN {$table_name} lp $pieces['join'] .= "LEFT JOIN {$table_name} as lp
ON {$order_table}.id = lp.id ON {$order_table}.id = lp.id
LEFT JOIN {$order_table} orders on {$order_table}.parent_order_id = orders.id"; LEFT JOIN {$order_table} as parent_order on {$order_table}.parent_order_id = parent_order.id";
return $pieces; return $pieces;
} }

View File

@@ -92,6 +92,18 @@ class WC_Subscription extends WC_Order {
'suspension_count', 'suspension_count',
); );
/**
* The meta key used to flag that the subscription's payment failed.
*
* Stored on the renewal order itself.
*
* Payments via the Block checkout transition the order status from failed to pending and then to processing.
* This makes it impossible for us to know if the order was initially failed. This meta key flags that the order was initially failed.
*
* @var string
*/
const RENEWAL_FAILED_META_KEY = '_failed_renewal_order';
/** /**
* Initializes a specific subscription if the ID is passed, otherwise a new and empty instance of a subscription. * Initializes a specific subscription if the ID is passed, otherwise a new and empty instance of a subscription.
* *
@@ -564,6 +576,9 @@ class WC_Subscription extends WC_Order {
// Use local copy of status transition value. // Use local copy of status transition value.
$status_transition = $this->status_transition; $status_transition = $this->status_transition;
// Reset status transition variable.
$this->status_transition = false;
// If we're not currently in the midst of a status transition, bail early. // If we're not currently in the midst of a status transition, bail early.
if ( ! $status_transition ) { if ( ! $status_transition ) {
return; return;
@@ -605,9 +620,6 @@ class WC_Subscription extends WC_Order {
); );
$this->add_order_note( __( 'Error during subscription status transition.', 'woocommerce-subscriptions' ) . ' ' . $e->getMessage() ); $this->add_order_note( __( 'Error during subscription status transition.', 'woocommerce-subscriptions' ) . ' ' . $e->getMessage() );
} }
// This has run, so reset status transition variable
$this->status_transition = false;
} }
/** /**
@@ -1862,6 +1874,8 @@ class WC_Subscription extends WC_Order {
do_action( 'woocommerce_subscription_payment_complete', $this ); do_action( 'woocommerce_subscription_payment_complete', $this );
if ( false !== $last_order && wcs_order_contains_renewal( $last_order ) ) { if ( false !== $last_order && wcs_order_contains_renewal( $last_order ) ) {
$last_order->delete_meta_data( self::RENEWAL_FAILED_META_KEY );
$last_order->save();
do_action( 'woocommerce_subscription_renewal_payment_complete', $this, $last_order ); do_action( 'woocommerce_subscription_renewal_payment_complete', $this, $last_order );
} }
} }
@@ -1876,10 +1890,17 @@ class WC_Subscription extends WC_Order {
// Make sure the last order's status is set to failed // Make sure the last order's status is set to failed
$last_order = $this->get_last_order( 'all', 'any' ); $last_order = $this->get_last_order( 'all', 'any' );
if ( false !== $last_order && false === $last_order->has_status( 'failed' ) ) { if ( false !== $last_order ) {
remove_filter( 'woocommerce_order_status_changed', 'WC_Subscriptions_Renewal_Order::maybe_record_subscription_payment' ); $last_order->update_meta_data( self::RENEWAL_FAILED_META_KEY, wc_bool_to_string( true ) );
$last_order->update_status( 'failed' );
add_filter( 'woocommerce_order_status_changed', 'WC_Subscriptions_Renewal_Order::maybe_record_subscription_payment', 10, 3 ); if ( false === $last_order->has_status( 'failed' ) ) {
remove_filter( 'woocommerce_order_status_changed', 'WC_Subscriptions_Renewal_Order::maybe_record_subscription_payment' );
$last_order->update_status( 'failed' );
add_filter( 'woocommerce_order_status_changed', 'WC_Subscriptions_Renewal_Order::maybe_record_subscription_payment', 10, 3 );
} else {
// If we didn't update the status, save the order to make sure our self::RENEWAL_FAILED_META_KEY meta data is saved.
$last_order->save();
}
} }
// Log payment failure on order // Log payment failure on order

View File

@@ -16,7 +16,7 @@ class WC_Subscriptions_Core_Plugin {
* The version of subscriptions-core library. * The version of subscriptions-core library.
* @var string * @var string
*/ */
protected $library_version = '6.9.0'; // WRCS: DEFINED_VERSION. protected $library_version = '7.0.0'; // WRCS: DEFINED_VERSION.
/** /**
* The subscription scheduler instance. * The subscription scheduler instance.

View File

@@ -57,6 +57,8 @@ class WC_Subscriptions_Manager {
// Do the same thing for WordPress networks // Do the same thing for WordPress networks
add_action( 'wpmu_delete_user', __CLASS__ . '::trash_users_subscriptions_for_network' ); add_action( 'wpmu_delete_user', __CLASS__ . '::trash_users_subscriptions_for_network' );
add_filter( 'woocommerce_cancel_unpaid_order', [ __CLASS__, 'exclude_subscription_from_order_cleanup' ], 10, 2 );
} }
/** /**
@@ -605,6 +607,22 @@ class WC_Subscriptions_Manager {
do_action( 'pending_subscription_created_for_order', $order, $product_id ); do_action( 'pending_subscription_created_for_order', $order, $product_id );
} }
/**
* Excludes subscriptions from the order cleanup process.
*
* @param bool $should_cancel Whether the order should be cancelled.
* @param WC_Order $order The order object.
*
* @return bool Whether the order should be cancelled.
*/
public static function exclude_subscription_from_order_cleanup( $should_cancel, $order ) {
if ( $should_cancel && 'shop_subscription' === $order->get_type() ) {
$should_cancel = false;
}
return $should_cancel;
}
/** /**
* Creates subscriptions against a users account with a status of pending when a user creates * Creates subscriptions against a users account with a status of pending when a user creates
* an order containing subscriptions. * an order containing subscriptions.

View File

@@ -127,7 +127,7 @@ class WC_Subscriptions_Renewal_Order {
if ( $order_completed && ! $subscription->has_status( wcs_get_subscription_ended_statuses() ) && ! $subscription->has_status( 'active' ) ) { if ( $order_completed && ! $subscription->has_status( wcs_get_subscription_ended_statuses() ) && ! $subscription->has_status( 'active' ) ) {
// Included here because calling payment_complete sets the retry status to 'cancelled' // Included here because calling payment_complete sets the retry status to 'cancelled'
$is_failed_renewal_order = 'failed' === $orders_old_status; $is_failed_renewal_order = 'failed' === $orders_old_status || wc_string_to_bool( $order->get_meta( WC_Subscription::RENEWAL_FAILED_META_KEY, true ) );
$is_failed_renewal_order = apply_filters( 'woocommerce_subscriptions_is_failed_renewal_order', $is_failed_renewal_order, $order_id, $orders_old_status ); $is_failed_renewal_order = apply_filters( 'woocommerce_subscriptions_is_failed_renewal_order', $is_failed_renewal_order, $order_id, $orders_old_status );
if ( $order_needed_payment ) { if ( $order_needed_payment ) {

View File

@@ -52,6 +52,26 @@ class WCS_Cart_Initial_Payment extends WCS_Cart_Renewal {
return; return;
} }
/**
* Filter whether to set up the cart during the pay-for-order payment flow.
*
* Allows developers to bypass cart setup for the pay-for-order payment flow.
* This is intended for situations in which re-creating the cart will result in
* the loss of order data.
*
* @since 6.2.0
*
* @param bool $recreate_cart Whether to recreate the initial payment order. Default true.
* @param WC_Order $order The order object.
* @param string $order_key The order key.
* @param int $order_id The order ID.
*/
$recreate_cart = apply_filters( "wcs_setup_cart_for_{$this->cart_item_key}", true, $order, $order_key, $order_id );
if ( ! $recreate_cart ) {
return;
}
if ( ! is_user_logged_in() ) { if ( ! is_user_logged_in() ) {
// Allow the customer to login first and then redirect them back. // Allow the customer to login first and then redirect them back.
$redirect = add_query_arg( $redirect = add_query_arg(

View File

@@ -494,33 +494,44 @@ class WCS_Cart_Renewal {
* Returns address details from the renewal order if the checkout is for a renewal. * Returns address details from the renewal order if the checkout is for a renewal.
* *
* @param string $value Default checkout field value. * @param string $value Default checkout field value.
* @param string $key The checkout form field name/key * @param string $key The checkout form field name/key.
*
* @return string $value Checkout field value. * @return string $value Checkout field value.
*/ */
public function checkout_get_value( $value, $key ) { public function checkout_get_value( $value, $key ) {
// Only hook in after WC()->checkout() has been initialised // Only hook in after WC()->checkout() has been initialised.
if ( $this->cart_contains() && did_action( 'woocommerce_checkout_init' ) > 0 ) { if ( ! $this->cart_contains() || did_action( 'woocommerce_checkout_init' ) <= 0 ) {
return $value;
}
// Guard against the fake WC_Checkout singleton, see https://github.com/woocommerce/woocommerce-subscriptions/issues/427#issuecomment-260763250 // Get the most specific order object, which will be the renewal order for renewals, initial order for initial payments, or a subscription for switches/resubscribes.
remove_filter( 'woocommerce_checkout_get_value', array( &$this, 'checkout_get_value' ), 10 ); $order = $this->get_order();
if ( is_callable( array( WC()->checkout(), 'get_checkout_fields' ) ) ) { // WC 3.0+ if ( ! $order ) {
$address_fields = array_merge( WC()->checkout()->get_checkout_fields( 'billing' ), WC()->checkout()->get_checkout_fields( 'shipping' ) ); return $value;
} else { }
$address_fields = array_merge( WC()->checkout()->checkout_fields['billing'], WC()->checkout()->checkout_fields['shipping'] );
}
add_filter( 'woocommerce_checkout_get_value', array( &$this, 'checkout_get_value' ), 10, 2 ); $address_fields = array_merge(
WC()->countries->get_address_fields(
$order->get_billing_country(),
'billing_'
),
WC()->countries->get_address_fields(
$order->get_shipping_country(),
'shipping_'
)
);
if ( array_key_exists( $key, $address_fields ) && false !== ( $item = $this->cart_contains() ) ) { // Generate the address getter method for the key.
$getter = "get_{$key}";
// Get the most specific order object, which will be the renewal order for renewals, initial order for initial payments, or a subscription for switches/resubscribes if ( array_key_exists( $key, $address_fields ) && is_callable( [ $order, $getter ] ) ) {
$order = $this->get_order( $item ); $order_value = call_user_func( [ $order, $getter ] );
if ( ( $order_value = wcs_get_objects_property( $order, $key ) ) ) { // Given this is fetching the value for a checkout field, we need to ensure the value is a scalar.
$value = $order_value; if ( is_scalar( $order_value ) ) {
} $value = $order_value;
} }
} }

View File

@@ -511,11 +511,11 @@ class WCS_PayPal {
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.5.3 * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.5.3
*/ */
public static function maybe_add_payment_lock() { public static function maybe_add_payment_lock() {
if ( ! wcs_is_order_received_page() ) { global $wp;
if ( ! isset( $wp->query_vars['order-received'] ) ) {
return; return;
} }
global $wp;
$order = wc_get_order( absint( $wp->query_vars['order-received'] ) ); $order = wc_get_order( absint( $wp->query_vars['order-received'] ) );
if ( $order && self::instance()->get_id() === $order->get_payment_method() && $order->needs_payment() && ! self::are_reference_transactions_enabled() && wcs_order_contains_subscription( $order, array( 'parent' ) ) ) { if ( $order && self::instance()->get_id() === $order->get_payment_method() && $order->needs_payment() && ! self::are_reference_transactions_enabled() && wcs_order_contains_subscription( $order, array( 'parent' ) ) ) {

View File

@@ -6,5 +6,5 @@
* Author: Automattic * Author: Automattic
* Author URI: https://woocommerce.com/ * Author URI: https://woocommerce.com/
* Requires WP: 5.6 * Requires WP: 5.6
* Version: 6.9.0 * Version: 7.0.0
*/ */

View File

@@ -5,7 +5,8 @@
* Description: Sell products and services with recurring payments in your WooCommerce Store. * Description: Sell products and services with recurring payments in your WooCommerce Store.
* Author: WooCommerce * Author: WooCommerce
* Author URI: https://woocommerce.com/ * Author URI: https://woocommerce.com/
* Version: 6.1.0 * Version: 6.2.0
* Requires Plugins: woocommerce
* *
* WC requires at least: 7.7.0 * WC requires at least: 7.7.0
* WC tested up to: 8.7.0 * WC tested up to: 8.7.0
@@ -77,7 +78,7 @@ class WC_Subscriptions {
public static $plugin_file = __FILE__; public static $plugin_file = __FILE__;
/** @var string */ /** @var string */
public static $version = '6.1.0'; // WRCS: DEFINED_VERSION. public static $version = '6.2.0'; // WRCS: DEFINED_VERSION.
/** @var string */ /** @var string */
public static $wc_minimum_supported_version = '7.7'; public static $wc_minimum_supported_version = '7.7';