This commit is contained in:
Prospress Inc
2017-11-17 15:51:17 +01:00
committed by Remco Tolsma
parent b8ef3dedff
commit d6629346ff
20 changed files with 224 additions and 130 deletions

View File

@@ -1,5 +1,24 @@
*** WooCommerce Subscriptions Changelog ***
2017.11.07 - version 2.2.15
* Fix: Don't include auto-draft subscriptions in the current subscriptions count in reports. PR#2414
* Fix: Reset cart item prorated amounts between calculations to avoid displaying double prorated prices. PR#2413
* Fix: Fix typo in "wcs_api_subscription_updated" hook - previously "wc_api_subscription_updated". PR#2364
* Fix: [WC3.2] Replace use of deprecated function with wc_get_checkout_url(). PR#2421
* Fix: Fix fatal error thrown while copying coupon line item meta between orders and subscriptions. PR#2426
* Tweak: [WC3.2] Add WC tested up to plugin header args. PR#2424
* Tweak: Introduce filter to give third-parties the ability to prevent customers from removing individual subscription line items. PR#2419
2017.11.01 - version 2.2.14
* Fix: [WC3.2] Update use of deprecated cart fee functions to use new APIs introduced in WC 3.2. PR#2397
* Fix: [WC3.2] Ensure line item download links are included in subscription related order emails. PR#2396
* Fix: Copy coupon line items from subscriptions to renewal orders. PR#2374
* Fix: Only apply recurring coupons to subscription products in parent orders #2375
* Fix: Allow for custom field IDs when saving subscription shipping and billing fields. PR#2392
* Tweak: Only save the order once when copying meta data between subscription and order objects - improves performance. PR#2383
* Tweak: Trigger a do_action when an error occurs during the renewal order creation process. PR#2403
* Tweak: Improve PayPal Standard error handling of IPNs which refer to subscriptions created with other systems. PR##2384
2017.10.13 - version 2.2.13
* Fix: Ensure wcs_get_subscriptions() returns the correct results when called with the 'customer_id' and 'product_id' arguments PR#2337
* Fix: Always set the order key when manually creating subscriptions from the admin dashboard PR#2350

View File

@@ -284,22 +284,22 @@ class WCS_Meta_Box_Subscription_Data extends WC_Meta_Box_Order_Data {
// Handle the billing fields.
foreach ( self::$billing_fields as $key => $field ) {
$prefixed_key = "_billing_{$key}";
if ( ! isset( $_POST[ $prefixed_key ] ) ) {
$field['id'] = isset( $field['id'] ) ? $field['id'] : "_billing_{$key}";
if ( ! isset( $_POST[ $field['id'] ] ) ) {
continue;
}
wcs_set_objects_property( $subscription, $prefixed_key, wc_clean( $_POST[ $prefixed_key ] ) );
wcs_set_objects_property( $subscription, $field['id'], wc_clean( $_POST[ $field['id'] ] ) );
}
// Handle the shipping fields.
foreach ( self::$shipping_fields as $key => $field ) {
$prefixed_key = "_shipping_{$key}";
if ( ! isset( $_POST[ $prefixed_key ] ) ) {
$field['id'] = isset( $field['id'] ) ? $field['id'] : "_shipping_{$key}";
if ( ! isset( $_POST[ $field['id'] ] ) ) {
continue;
}
wcs_set_objects_property( $subscription, $prefixed_key, wc_clean( $_POST[ $prefixed_key ] ) );
wcs_set_objects_property( $subscription, $field['id'], wc_clean( $_POST[ $field['id'] ] ) );
}
try {

View File

@@ -257,7 +257,7 @@ class WC_Report_Subscription_Events_By_Date extends WC_Admin_Report {
ON wcsubs.ID = wcsmeta.post_id AND wcsmeta.meta_key = %s
) ON DATE( wcsubs.post_date ) <= searchdate.Date
AND wcsubs.post_type IN ( 'shop_subscription' )
AND wcsubs.post_status NOT IN( 'wc-pending', 'trash' )
AND wcsubs.post_status NOT IN( 'wc-pending', 'trash', 'auto-draft' )
AND (
DATE( wcsmeta.meta_value ) >= searchdate.Date
OR wcsmeta.meta_value = 0

View File

@@ -2053,7 +2053,7 @@ class WC_Subscription extends WC_Order {
* @return bool
*/
public function is_download_permitted() {
$sending_email = did_action( 'woocommerce_email_before_order_table' ) > did_action( 'woocommerce_email_after_order_table' );
$sending_email = did_action( 'woocommerce_email_header' ) > did_action( 'woocommerce_email_footer' );
$is_download_permitted = $this->has_status( 'active' ) || $this->has_status( 'pending-cancel' );
// WC Emails are sent before the subscription status is updated to active etc. so we need a way to ensure download links are added to the emails before being sent

View File

@@ -304,7 +304,12 @@ class WC_Subscriptions_Cart {
self::$cached_recurring_cart = $recurring_cart;
// No fees recur (yet)
$recurring_cart->fees = array();
if ( is_callable( array( $recurring_cart, 'fees_api' ) ) ) { // WC 3.2 +
$recurring_cart->fees_api()->remove_all_fees();
} else {
$recurring_cart->fees = array();
}
$recurring_cart->fee_total = 0;
WC()->shipping->reset_shipping();
self::maybe_restore_shipping_methods();
@@ -333,9 +338,21 @@ class WC_Subscriptions_Cart {
// If there is no sign-up fee and a free trial, and no products being purchased with the subscription, we need to zero the fees for the first billing period
if ( 0 == self::get_cart_subscription_sign_up_fee() && self::all_cart_items_have_free_trial() ) {
foreach ( WC()->cart->get_fees() as $fee_index => $fee ) {
WC()->cart->fees[ $fee_index ]->amount = 0;
WC()->cart->fees[ $fee_index ]->tax = 0;
$cart_fees = WC()->cart->get_fees();
if ( WC_Subscriptions::is_woocommerce_pre( '3.2' ) ) {
foreach ( $cart_fees as $fee_index => $fee ) {
WC()->cart->fees[ $fee_index ]->amount = 0;
WC()->cart->fees[ $fee_index ]->tax = 0;
}
} else {
foreach ( $cart_fees as $fee ) {
$fee->amount = 0;
$fee->tax = 0;
$fee->total = 0;
}
WC()->cart->fees_api()->set_fees( $cart_fees );
}
WC()->cart->fee_total = 0;
}

View File

@@ -245,8 +245,8 @@ class WC_Subscriptions_Coupon {
$order = $line_item->get_order();
$product = $line_item->get_product();
// Recurring coupons can be applied to subscriptions or any order which contains a subscription
if ( in_array( $coupon_type, array( 'recurring_fee', 'recurring_percent' ) ) && ( wcs_is_subscription( $order ) || wcs_order_contains_subscription( $order, 'any' ) ) ) {
// Recurring coupons can be applied to subscriptions, any renewal line item or subscription products in other order types
if ( in_array( $coupon_type, array( 'recurring_fee', 'recurring_percent' ) ) && ( wcs_is_subscription( $order ) || wcs_order_contains_renewal( $order ) || WC_Subscriptions_Product::is_subscription( $product ) ) ) {
if ( 'recurring_fee' === $coupon_type ) {
$discount = min( $coupon->get_amount(), $discounting_amount );
$discount = $single ? $discount : $discount * $line_item->get_quantity();

View File

@@ -1444,6 +1444,12 @@ class WC_Subscriptions_Switcher {
}
} else {
// If we've already calculated the prorated price recalculate the amounts but reset the values so we don't double the amounts
if ( 0 < wcs_get_objects_property( WC()->cart->cart_contents[ $cart_item_key ]['data'], 'subscription_price_prorated', 'single', 0 ) ) {
$prorated_signup_fee = wcs_get_objects_property( WC()->cart->cart_contents[ $cart_item_key ]['data'], 'subscription_sign_up_fee_prorated', 'single' );
wcs_set_objects_property( WC()->cart->cart_contents[ $cart_item_key ]['data'], 'subscription_sign_up_fee', $prorated_signup_fee, 'set_prop_only' );
}
$extra_to_pay = $days_until_next_payment * ( $new_price_per_day - $old_price_per_day );
// when calculating a subscription with one length (no more next payment date and the end date may have been pushed back) we need to pay for those extra days at the new price per day between the old next payment date and new end date

View File

@@ -70,7 +70,7 @@ class WCS_Cart_Initial_Payment extends WCS_Cart_Renewal {
// Set cart hash for orders paid in WC >= 2.6
$this->set_cart_hash( $order_id );
wp_safe_redirect( WC()->cart->get_checkout_url() );
wp_safe_redirect( wc_get_checkout_url() );
exit;
}
}

View File

@@ -204,7 +204,7 @@ class WCS_Cart_Renewal {
wc_add_notice( __( 'Complete checkout to renew your subscription.', 'woocommerce-subscriptions' ), 'success' );
}
wp_safe_redirect( WC()->cart->get_checkout_url() );
wp_safe_redirect( wc_get_checkout_url() );
exit;
}
}

View File

@@ -91,7 +91,7 @@ class WCS_Cart_Resubscribe extends WCS_Cart_Renewal {
wc_add_notice( __( 'Complete checkout to resubscribe.', 'woocommerce-subscriptions' ), 'success' );
}
$redirect_to = WC()->cart->get_checkout_url();
$redirect_to = wc_get_checkout_url();
}
wp_safe_redirect( $redirect_to );
@@ -132,8 +132,7 @@ class WCS_Cart_Resubscribe extends WCS_Cart_Renewal {
}
}
$redirect_to = WC()->cart->get_checkout_url();
wp_safe_redirect( $redirect_to );
wp_safe_redirect( wc_get_checkout_url() );
exit;
}
}

View File

@@ -134,7 +134,7 @@ class WCS_Cart_Switch extends WCS_Cart_Renewal {
WC()->session->set( 'order_awaiting_payment', $order_id );
$this->set_cart_hash( $order_id );
wp_safe_redirect( WC()->cart->get_checkout_url() );
wp_safe_redirect( wc_get_checkout_url() );
exit;
}
}

View File

@@ -79,7 +79,7 @@ class WCS_Webhooks {
'woocommerce_process_shop_subscription_meta',
),
'subscription.updated' => array(
'wc_api_subscription_updated',
'wcs_api_subscription_updated',
'woocommerce_subscription_status_changed',
'wcs_webhook_subscription_updated',
'woocommerce_process_shop_subscription_meta',

View File

@@ -93,26 +93,34 @@ class WCS_PayPal_Standard_IPN_Handler extends WC_Gateway_Paypal_IPN_Handler {
return;
}
// If the IPN is for a cancellation after a failed payment on a PayPal Standard subscription created with Subscriptions < 2.0, the subscription won't be found, but that doesn't mean we should throw an exception, we should just ignore it
if ( empty( $subscription ) && in_array( $transaction_details['txn_type'], array( 'subscr_cancel', 'subscr_eot' ) ) ) {
if ( empty( $subscription ) ) {
// Check if the reason the subscription can't be found is because it has since been changed to a new PayPal Subscription and this IPN is for the cancellation after a renewal sign-up
$subscription_id_and_key = self::get_order_id_and_key( $transaction_details, 'shop_subscription', '_old_paypal_subscriber_id' );
// If the IPN is for a cancellation after a failed payment on a PayPal Standard subscription created with Subscriptions < 2.0, the subscription won't be found, but that doesn't mean we should throw an exception, we should just ignore it
if ( in_array( $transaction_details['txn_type'], array( 'subscr_cancel', 'subscr_eot' ) ) ) {
if ( ! empty( $subscription_id_and_key['order_id'] ) ) {
WC_Gateway_Paypal::log( 'IPN subscription cancellation request ignored - new PayPal Profile ID linked to this subscription, for subscription ' . $subscription_id_and_key['order_id'] );
return;
// Check if the reason the subscription can't be found is because it has since been changed to a new PayPal Subscription and this IPN is for the cancellation after a renewal sign-up
$subscription_id_and_key = self::get_order_id_and_key( $transaction_details, 'shop_subscription', '_old_paypal_subscriber_id' );
if ( ! empty( $subscription_id_and_key['order_id'] ) ) {
WC_Gateway_Paypal::log( 'IPN subscription cancellation request ignored - new PayPal Profile ID linked to this subscription, for subscription ' . $subscription_id_and_key['order_id'] );
return;
}
}
}
// If the IPN is for a suspension after a switch on a PayPal Standard subscription created with Subscriptions < 2.0, the subscription won't be found, but that doesn't mean we should throw an exception, we should just ignore it
if ( empty( $subscription ) && 'recurring_payment_suspended' === $transaction_details['txn_type'] ) {
// If the IPN is for a suspension after a switch on a PayPal Standard subscription created with Subscriptions < 2.0, the subscription won't be found, but that doesn't mean we should throw an exception, we should just ignore it
if ( 'recurring_payment_suspended' === $transaction_details['txn_type'] ) {
// Check if the reason the subscription can't be found is because it has since been changed after a successful subscription switch
$subscription_id_and_key = self::get_order_id_and_key( $transaction_details, 'shop_subscription', '_switched_paypal_subscription_id' );
// Check if the reason the subscription can't be found is because it has since been changed after a successful subscription switch
$subscription_id_and_key = self::get_order_id_and_key( $transaction_details, 'shop_subscription', '_switched_paypal_subscription_id' );
if ( ! empty( $subscription_id_and_key['order_id'] ) ) {
WC_Gateway_Paypal::log( 'IPN subscription suspension request ignored - subscription payment gateway changed via switch' . $subscription_id_and_key['order_id'] );
if ( ! empty( $subscription_id_and_key['order_id'] ) ) {
WC_Gateway_Paypal::log( 'IPN subscription suspension request ignored - subscription payment gateway changed via switch' . $subscription_id_and_key['order_id'] );
return;
}
}
if ( empty( $transaction_details['custom'] ) || ! $this->is_woocommerce_payload( $transaction_details['custom'] ) ) {
WC_Gateway_Paypal::log( 'IPN request ignored - payload is not in a WooCommerce recognizable format' );
return;
}
}
@@ -537,6 +545,23 @@ class WCS_PayPal_Standard_IPN_Handler extends WC_Gateway_Paypal_IPN_Handler {
return $this->transaction_types;
}
/**
* Checks if a string may include a WooCommerce order key.
*
* This function expects a generic payload, in any serialization format. It looks for an 'order key' code. This
* function uses regular expressions and looks for 'order key'. WooCommerce allows plugins to modify the order
* keys through filtering, unfortunatelly we only check for the original
*
* @param string $payload PayPal payload data
*
* @return bool
*/
protected function is_woocommerce_payload( $payload ) {
return is_numeric( $payload ) ||
(bool) preg_match( '/(wc_)?order_[a-f0-9]{5,20}/', $payload );
}
/**
* Checks a set of args and derives an Order ID with backward compatibility for WC < 1.7 where 'custom' was the Order ID.
*

View File

@@ -153,6 +153,8 @@ function wcs_copy_order_meta( $from_order, $to_order, $type = 'subscription' ) {
'_date_paid',
'_completed_date',
'_date_completed',
'_edit_last',
'_subscription_switch_data',
'_order_key',
'_edit_lock',
'_wc_points_earned',
@@ -177,8 +179,15 @@ function wcs_copy_order_meta( $from_order, $to_order, $type = 'subscription' ) {
$meta = $wpdb->get_results( $meta_query, 'ARRAY_A' );
$meta = apply_filters( 'wcs_' . $type . '_meta', $meta, $to_order, $from_order );
// Pre WC 3.0 we need to save each meta individually, post 3.0 we can save the object once
$save = WC_Subscriptions::is_woocommerce_pre( '3.0' ) ? 'save' : 'set_prop_only';
foreach ( $meta as $meta_item ) {
wcs_set_objects_property( $to_order, $meta_item['meta_key'], maybe_unserialize( $meta_item['meta_value'] ), 'save', '', 'omit_key_prefix' );
wcs_set_objects_property( $to_order, $meta_item['meta_key'], maybe_unserialize( $meta_item['meta_value'] ), $save, '', 'omit_key_prefix' );
}
if ( is_callable( array( $to_order, 'save' ) ) ) {
$to_order->save();
}
}
@@ -216,7 +225,7 @@ function wcs_create_order_from_subscription( $subscription, $type ) {
wcs_copy_order_meta( $subscription, $new_order, $type );
// Copy over line items and allow extensions to add/remove items or item meta
$items = apply_filters( 'wcs_new_order_items', $subscription->get_items( array( 'line_item', 'fee', 'shipping', 'tax' ) ), $new_order, $subscription );
$items = apply_filters( 'wcs_new_order_items', $subscription->get_items( array( 'line_item', 'fee', 'shipping', 'tax', 'coupon' ) ), $new_order, $subscription );
$items = apply_filters( 'wcs_' . $type . '_items', $items, $new_order, $subscription );
foreach ( $items as $item_index => $item ) {
@@ -394,7 +403,7 @@ function wcs_get_order_address( $order, $address_type = 'shipping' ) {
* Checks an order to see if it contains a subscription.
*
* @param mixed $order A WC_Order object or the ID of the order which the subscription was purchased in.
* @param array|string $order_type Can include 'parent', 'renewal', 'resubscribe' and/or 'switch'. Defaults to 'parent'.
* @param array|string $order_type Can include 'parent', 'renewal', 'resubscribe' and/or 'switch'. Defaults to 'parent', 'resubscribe' and 'switch' orders.
* @return bool True if the order contains a subscription that belongs to any of the given order types, otherwise false.
* @since 2.0
*/
@@ -783,8 +792,8 @@ function wcs_copy_order_item( $from_item, &$to_item ) {
break;
case 'coupon':
$to_item->set_props( array(
'discount' => $from_item->discount(),
'discount_tax' => $from_item->discount_tax(),
'discount' => $from_item->get_discount(),
'discount_tax' => $from_item->get_discount_tax(),
) );
break;
}

View File

@@ -29,6 +29,7 @@ function wcs_create_renewal_order( $subscription ) {
$renewal_order = wcs_create_order_from_subscription( $subscription, 'renewal_order' );
if ( is_wp_error( $renewal_order ) ) {
do_action( 'wcs_failed_to_create_renewal_order', $renewal_order, $subscription );
return new WP_Error( 'renewal-order-error', $renewal_order->get_error_message() );
}

View File

@@ -2,10 +2,10 @@
# This file is distributed under the same license as the WooCommerce Subscriptions package.
msgid ""
msgstr ""
"Project-Id-Version: WooCommerce Subscriptions 2.2.13\n"
"Project-Id-Version: WooCommerce Subscriptions 2.2.15\n"
"Report-Msgid-Bugs-To: "
"https://github.com/Prospress/woocommerce-subscriptions/issues\n"
"POT-Creation-Date: 2017-10-13 08:02:19+00:00\n"
"POT-Creation-Date: 2017-11-07 04:27:49+00:00\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -180,7 +180,7 @@ msgid "Manage Subscriptions"
msgstr ""
#: includes/admin/class-wc-subscriptions-admin.php:873
#: woocommerce-subscriptions.php:236
#: woocommerce-subscriptions.php:238
msgid "Search Subscriptions"
msgstr ""
@@ -190,7 +190,7 @@ msgstr ""
#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:654
#: includes/class-wcs-query.php:95 includes/class-wcs-query.php:115
#: includes/class-wcs-query.php:117 templates/admin/status.php:9
#: woocommerce-subscriptions.php:227 woocommerce-subscriptions.php:240
#: woocommerce-subscriptions.php:229 woocommerce-subscriptions.php:242
msgid "Subscriptions"
msgstr ""
@@ -215,7 +215,7 @@ msgstr ""
#: includes/class-wc-product-subscription.php:72
#: includes/class-wc-product-variable-subscription.php:63
#: includes/class-wc-subscriptions-product.php:96
#: woocommerce-subscriptions.php:487
#: woocommerce-subscriptions.php:489
msgid "Sign Up Now"
msgstr ""
@@ -350,7 +350,7 @@ msgstr ""
#: includes/admin/class-wc-subscriptions-admin.php:1200
#: includes/upgrades/templates/wcs-about-2-0.php:35
#: includes/upgrades/templates/wcs-about.php:34
#: woocommerce-subscriptions.php:1026
#: woocommerce-subscriptions.php:1028
msgid "Settings"
msgstr ""
@@ -544,7 +544,7 @@ msgstr ""
#: templates/emails/subscription-info.php:18
#: templates/myaccount/my-subscriptions.php:25
#: templates/myaccount/related-subscriptions.php:20
#: woocommerce-subscriptions.php:228
#: woocommerce-subscriptions.php:230
msgid "Subscription"
msgstr ""
@@ -1544,7 +1544,7 @@ msgstr ""
#: includes/class-wc-subscription.php:2365
#: includes/class-wc-subscriptions-checkout.php:313
#: includes/wcs-order-functions.php:279
#: includes/wcs-order-functions.php:288
msgid "Backordered"
msgstr ""
@@ -1564,21 +1564,21 @@ msgstr ""
msgid "Update the %1$s used for %2$sall%3$s of my active subscriptions"
msgstr ""
#: includes/class-wc-subscriptions-cart.php:872
#: includes/class-wc-subscriptions-cart.php:889
msgid "Please enter a valid postcode/ZIP."
msgstr ""
#: includes/class-wc-subscriptions-cart.php:1043
#: includes/class-wc-subscriptions-cart.php:1060
msgid ""
"That subscription product can not be added to your cart as it already "
"contains a subscription renewal."
msgstr ""
#: includes/class-wc-subscriptions-cart.php:1131
#: includes/class-wc-subscriptions-cart.php:1148
msgid "Invalid recurring shipping method."
msgstr ""
#: includes/class-wc-subscriptions-cart.php:1897
#: includes/class-wc-subscriptions-cart.php:1914
msgid "now"
msgstr ""
@@ -2072,7 +2072,7 @@ msgstr ""
#: includes/class-wc-subscriptions-switcher.php:408
#: includes/class-wc-subscriptions-switcher.php:434
#: includes/class-wc-subscriptions-switcher.php:2357
#: includes/class-wc-subscriptions-switcher.php:2363
msgid "Upgrade or Downgrade"
msgstr ""
@@ -2110,16 +2110,16 @@ msgstr ""
msgid "There was an error locating the switch details."
msgstr ""
#: includes/class-wc-subscriptions-switcher.php:1923
#: includes/class-wc-subscriptions-switcher.php:2263
#: includes/class-wc-subscriptions-switcher.php:1929
#: includes/class-wc-subscriptions-switcher.php:2269
msgid "The original subscription item being switched cannot be found."
msgstr ""
#: includes/class-wc-subscriptions-switcher.php:1925
#: includes/class-wc-subscriptions-switcher.php:1931
msgid "The item on the switch order cannot be found."
msgstr ""
#: includes/class-wc-subscriptions-switcher.php:2301
#: includes/class-wc-subscriptions-switcher.php:2307
msgid "Failed to update the subscription shipping method."
msgstr ""
@@ -2268,7 +2268,7 @@ msgstr ""
msgid "Complete checkout to resubscribe."
msgstr ""
#: includes/class-wcs-cart-resubscribe.php:314
#: includes/class-wcs-cart-resubscribe.php:313
msgid "Customer resubscribed in order #%s"
msgstr ""
@@ -2761,32 +2761,32 @@ msgstr ""
msgid "Billing agreement cancelled at PayPal."
msgstr ""
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:270
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:278
msgid "IPN subscription sign up completed."
msgstr ""
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:313
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:390
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:321
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:398
msgid "IPN subscription payment completed."
msgstr ""
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:352
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:360
msgid "IPN subscription failing payment method changed."
msgstr ""
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:442
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:450
msgid "IPN subscription suspended."
msgstr ""
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:465
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:473
msgid "IPN subscription cancelled."
msgstr ""
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:481
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:489
msgid "IPN subscription payment failure."
msgstr ""
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:602
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:627
msgid "Invalid PayPal IPN Payload: unable to find matching subscription."
msgstr ""
@@ -3683,27 +3683,27 @@ msgstr ""
msgid "MM"
msgstr ""
#: includes/wcs-order-functions.php:318
#: includes/wcs-order-functions.php:327
msgid "Subscription Renewal Order &ndash; %s"
msgstr ""
#: includes/wcs-order-functions.php:321
#: includes/wcs-order-functions.php:330
msgid "Resubscribe Order &ndash; %s"
msgstr ""
#: includes/wcs-order-functions.php:340
#: includes/wcs-order-functions.php:349
msgid "$type passed to the function was not a string."
msgstr ""
#: includes/wcs-order-functions.php:345
#: includes/wcs-order-functions.php:354
msgid "\"%s\" is not a valid new order type."
msgstr ""
#: includes/wcs-order-functions.php:532
#: includes/wcs-order-functions.php:541
msgid "Invalid data. No valid subscription / order was passed in."
msgstr ""
#: includes/wcs-order-functions.php:536
#: includes/wcs-order-functions.php:545
msgid "Invalid data. No valid item id was passed in."
msgstr ""
@@ -4006,7 +4006,7 @@ msgstr ""
msgid "Subscription Totals"
msgstr ""
#: templates/myaccount/view-subscription.php:109
#: templates/myaccount/view-subscription.php:110
msgid "Are you sure you want remove this item from your subscription?"
msgstr ""
@@ -4047,71 +4047,71 @@ msgstr ""
msgid "Date type can not be an empty string."
msgstr ""
#: woocommerce-subscriptions.php:242
#: woocommerce-subscriptions.php:244
msgid "This is where subscriptions are stored."
msgstr ""
#: woocommerce-subscriptions.php:287
#: woocommerce-subscriptions.php:289
msgid "No Subscriptions found"
msgstr ""
#: woocommerce-subscriptions.php:289
#: woocommerce-subscriptions.php:291
msgid ""
"Subscriptions will appear here for you to view and manage once purchased by "
"a customer."
msgstr ""
#: woocommerce-subscriptions.php:291
#: woocommerce-subscriptions.php:293
#. translators: placeholders are opening and closing link tags
msgid "%sLearn more about managing subscriptions &raquo;%s"
msgstr ""
#: woocommerce-subscriptions.php:293
#: woocommerce-subscriptions.php:295
#. translators: placeholders are opening and closing link tags
msgid "%sAdd a subscription product &raquo;%s"
msgstr ""
#: woocommerce-subscriptions.php:407
#: woocommerce-subscriptions.php:409
msgid ""
"A subscription renewal has been removed from your cart. Multiple "
"subscriptions can not be purchased at the same time."
msgstr ""
#: woocommerce-subscriptions.php:413
#: woocommerce-subscriptions.php:415
msgid ""
"A subscription has been removed from your cart. Due to payment gateway "
"restrictions, different subscription products can not be purchased at the "
"same time."
msgstr ""
#: woocommerce-subscriptions.php:419
#: woocommerce-subscriptions.php:421
msgid ""
"A subscription has been removed from your cart. Products and subscriptions "
"can not be purchased at the same time."
msgstr ""
#: woocommerce-subscriptions.php:556 woocommerce-subscriptions.php:573
#: woocommerce-subscriptions.php:558 woocommerce-subscriptions.php:575
#. translators: placeholder is a number, this is for the teens
#. translators: placeholder is a number, numbers ending in 4-9, 0
msgid "%sth"
msgstr ""
#: woocommerce-subscriptions.php:561
#: woocommerce-subscriptions.php:563
#. translators: placeholder is a number, numbers ending in 1
msgid "%sst"
msgstr ""
#: woocommerce-subscriptions.php:565
#: woocommerce-subscriptions.php:567
#. translators: placeholder is a number, numbers ending in 2
msgid "%snd"
msgstr ""
#: woocommerce-subscriptions.php:569
#: woocommerce-subscriptions.php:571
#. translators: placeholder is a number, numbers ending in 3
msgid "%srd"
msgstr ""
#: woocommerce-subscriptions.php:599
#: woocommerce-subscriptions.php:601
#. translators: 1$-2$: opening and closing <strong> tags, 3$-4$: link tags,
#. takes to woocommerce plugin on wp.org, 5$-6$: opening and closing link tags,
#. leads to plugins.php in admin
@@ -4121,7 +4121,7 @@ msgid ""
"%5$sinstall & activate WooCommerce &raquo;%6$s"
msgstr ""
#: woocommerce-subscriptions.php:606
#: woocommerce-subscriptions.php:608
#. translators: 1$-2$: opening and closing <strong> tags, 3$-4$: opening and
#. closing link tags, leads to plugin admin
msgid ""
@@ -4130,11 +4130,11 @@ msgid ""
"WooCommerce to version 2.4 or newer &raquo;%4$s"
msgstr ""
#: woocommerce-subscriptions.php:632
#: woocommerce-subscriptions.php:634
msgid "Variable Subscription"
msgstr ""
#: woocommerce-subscriptions.php:819
#: woocommerce-subscriptions.php:821
#. translators: 1$-2$: opening and closing <strong> tags, 3$-4$: opening and
#. closing link tags. Leads to duplicate site article on docs
msgid ""
@@ -4144,19 +4144,19 @@ msgid ""
"environment. %3$sLearn more &raquo;%4$s."
msgstr ""
#: woocommerce-subscriptions.php:821
#: woocommerce-subscriptions.php:823
msgid "Quit nagging me (but don't enable automatic payments)"
msgstr ""
#: woocommerce-subscriptions.php:822
#: woocommerce-subscriptions.php:824
msgid "Enable automatic payments"
msgstr ""
#: woocommerce-subscriptions.php:1028
#: woocommerce-subscriptions.php:1030
msgid "Support"
msgstr ""
#: woocommerce-subscriptions.php:1133
#: woocommerce-subscriptions.php:1135
#. translators: placeholders are opening and closing tags. Leads to docs on
#. version 2
msgid ""
@@ -4167,14 +4167,14 @@ msgid ""
"2.0 &raquo;%s"
msgstr ""
#: woocommerce-subscriptions.php:1148
#: woocommerce-subscriptions.php:1150
msgid ""
"Warning! You are running version %s of WooCommerce Subscriptions plugin "
"code but your database has been upgraded to Subscriptions version 2.0. This "
"will cause major problems on your store."
msgstr ""
#: woocommerce-subscriptions.php:1149
#: woocommerce-subscriptions.php:1151
msgid ""
"Please upgrade the WooCommerce Subscriptions plugin to version 2.0 or newer "
"immediately. If you need assistance, after upgrading to Subscriptions v2.0, "
@@ -4561,7 +4561,7 @@ msgctxt "Subscription status"
msgid "On-hold"
msgstr ""
#: includes/class-wc-subscriptions-switcher.php:2498 wcs-functions.php:212
#: includes/class-wc-subscriptions-switcher.php:2504 wcs-functions.php:212
msgctxt "Subscription status"
msgid "Switched"
msgstr ""
@@ -4683,30 +4683,30 @@ msgctxt "when to prorate first payment / subscription length"
msgid "For All Subscription Products"
msgstr ""
#: includes/class-wc-subscriptions-switcher.php:1809
#: includes/class-wc-subscriptions-switcher.php:1815
msgctxt "a switch order"
msgid "Downgrade"
msgstr ""
#: includes/class-wc-subscriptions-switcher.php:1812
#: includes/class-wc-subscriptions-switcher.php:1818
msgctxt "a switch order"
msgid "Upgrade"
msgstr ""
#: includes/class-wc-subscriptions-switcher.php:1815
#: includes/class-wc-subscriptions-switcher.php:1821
msgctxt "a switch order"
msgid "Crossgrade"
msgstr ""
#: includes/class-wc-subscriptions-switcher.php:1820
#: includes/class-wc-subscriptions-switcher.php:1826
#. translators: %1: product subtotal, %2: HTML span tag, %3: direction
#. (upgrade, downgrade, crossgrade), %4: closing HTML span tag
msgctxt "product subtotal string"
msgid "%1$s %2$s(%3$s)%4$s"
msgstr ""
#: includes/class-wc-subscriptions-switcher.php:1936
#: includes/class-wc-subscriptions-switcher.php:2274
#: includes/class-wc-subscriptions-switcher.php:1942
#: includes/class-wc-subscriptions-switcher.php:2280
#. translators: 1$: old item, 2$: new item when switching
msgctxt "used in order notes"
msgid "Customer switched from: %1$s to %2$s."
@@ -4768,14 +4768,14 @@ msgctxt "used in order note"
msgid "Customer removed \"%1$s\" (Product ID: #%2$d) via the My Account page."
msgstr ""
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:400
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:409
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:408
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:417
#. translators: placeholder is payment status (e.g. "completed")
msgctxt "used in order note"
msgid "IPN subscription payment %s."
msgstr ""
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:413
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:421
#. translators: placeholder is payment status (e.g. "completed")
msgctxt "used in order note"
msgid "IPN subscription payment %s for reason: %s."
@@ -4978,7 +4978,7 @@ msgctxt "no information about something"
msgid "N/A"
msgstr ""
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:266
#: includes/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php:274
msgctxt ""
"when it is a payment change, and there is a subscr_signup message, this "
"will be a confirmation message that PayPal accepted it being the new "
@@ -5064,7 +5064,7 @@ msgid ""
msgstr ""
#: includes/upgrades/templates/wcs-about-2-0.php:36
#: woocommerce-subscriptions.php:1027
#: woocommerce-subscriptions.php:1029
msgctxt "short for documents"
msgid "Docs"
msgstr ""
@@ -5135,7 +5135,7 @@ msgctxt ""
msgid "Invalid data. Type of copy is not a string."
msgstr ""
#: includes/wcs-order-functions.php:314 wcs-functions.php:155
#: includes/wcs-order-functions.php:323 wcs-functions.php:155
#. translators: Order date parsed by strftime
msgctxt "Used in subscription post title. \"Subscription renewal order - <this>\""
msgid "%b %d, %Y @ %I:%M %p"
@@ -5542,68 +5542,68 @@ msgctxt "The post title for the new subscription"
msgid "Subscription &ndash; %s"
msgstr ""
#: woocommerce-subscriptions.php:229
#: woocommerce-subscriptions.php:231
msgctxt "custom post type setting"
msgid "Add Subscription"
msgstr ""
#: woocommerce-subscriptions.php:230
#: woocommerce-subscriptions.php:232
msgctxt "custom post type setting"
msgid "Add New Subscription"
msgstr ""
#: woocommerce-subscriptions.php:231
#: woocommerce-subscriptions.php:233
msgctxt "custom post type setting"
msgid "Edit"
msgstr ""
#: woocommerce-subscriptions.php:232
#: woocommerce-subscriptions.php:234
msgctxt "custom post type setting"
msgid "Edit Subscription"
msgstr ""
#: woocommerce-subscriptions.php:233
#: woocommerce-subscriptions.php:235
msgctxt "custom post type setting"
msgid "New Subscription"
msgstr ""
#: woocommerce-subscriptions.php:234 woocommerce-subscriptions.php:235
#: woocommerce-subscriptions.php:236 woocommerce-subscriptions.php:237
msgctxt "custom post type setting"
msgid "View Subscription"
msgstr ""
#: woocommerce-subscriptions.php:238
#: woocommerce-subscriptions.php:240
msgctxt "custom post type setting"
msgid "No Subscriptions found in trash"
msgstr ""
#: woocommerce-subscriptions.php:239
#: woocommerce-subscriptions.php:241
msgctxt "custom post type setting"
msgid "Parent Subscriptions"
msgstr ""
#: woocommerce-subscriptions.php:307
#: woocommerce-subscriptions.php:309
msgctxt "post status label including post count"
msgid "Active <span class=\"count\">(%s)</span>"
msgid_plural "Active <span class=\"count\">(%s)</span>"
msgstr[0] ""
msgstr[1] ""
#: woocommerce-subscriptions.php:308
#: woocommerce-subscriptions.php:310
msgctxt "post status label including post count"
msgid "Switched <span class=\"count\">(%s)</span>"
msgid_plural "Switched <span class=\"count\">(%s)</span>"
msgstr[0] ""
msgstr[1] ""
#: woocommerce-subscriptions.php:309
#: woocommerce-subscriptions.php:311
msgctxt "post status label including post count"
msgid "Expired <span class=\"count\">(%s)</span>"
msgid_plural "Expired <span class=\"count\">(%s)</span>"
msgstr[0] ""
msgstr[1] ""
#: woocommerce-subscriptions.php:310
#: woocommerce-subscriptions.php:312
msgctxt "post status label including post count"
msgid "Pending Cancellation <span class=\"count\">(%s)</span>"
msgid_plural "Pending Cancellation <span class=\"count\">(%s)</span>"

View File

@@ -6,5 +6,5 @@ Tested up to: 4.5
License: GPLv3
License URI: http://www.gnu.org/licenses/gpl-3.0.html
WC requires at least: 2.5
WC tested up to: 3.1
WC tested up to: 3.2
Woo: 27147:6115e6d7e297b623a169fdcf5728b224

View File

@@ -84,12 +84,12 @@ wc_print_notices();
<?php endforeach; ?>
</ol>
<?php endif; ?>
<?php $allow_remove_item = wcs_can_items_be_removed( $subscription ); ?>
<?php $allow_remove_items = wcs_can_items_be_removed( $subscription ); ?>
<h2><?php esc_html_e( 'Subscription Totals', 'woocommerce-subscriptions' ); ?></h2>
<table class="shop_table order_details">
<thead>
<tr>
<?php if ( $allow_remove_item ) : ?>
<?php if ( $allow_remove_items ) : ?>
<th class="product-remove" style="width: 3em;">&nbsp;</th>
<?php endif; ?>
<th class="product-name"><?php echo esc_html_x( 'Product', 'table headings in notification email', 'woocommerce-subscriptions' ); ?></th>
@@ -105,8 +105,13 @@ wc_print_notices();
if ( apply_filters( 'woocommerce_order_item_visible', true, $item ) ) {
?>
<tr class="<?php echo esc_attr( apply_filters( 'woocommerce_order_item_class', 'order_item', $item, $subscription ) ); ?>">
<?php if ( $allow_remove_item ) : ?>
<td class="remove_item"><a href="<?php echo esc_url( WCS_Remove_Item::get_remove_url( $subscription->get_id(), $item_id ) );?>" class="remove" onclick="return confirm('<?php printf( esc_html__( 'Are you sure you want remove this item from your subscription?', 'woocommerce-subscriptions' ) ); ?>');">&times;</a></td>
<td class="remove_item">
<?php if ( wcs_can_item_be_removed( $item, $subscription ) ) : ?>
<?php $confirm_notice = apply_filters( 'woocommerce_subscriptions_order_item_remove_confirmation_text', __( 'Are you sure you want remove this item from your subscription?', 'woocommerce-subscriptions' ), $item, $_product, $subscription );?>
<a href="<?php echo esc_url( WCS_Remove_Item::get_remove_url( $subscription->get_id(), $item_id ) );?>" class="remove" onclick="return confirm('<?php printf( esc_html( $confirm_notice ) ); ?>');">&times;</a>
<?php endif; ?>
</td>
<?php if ( $allow_remove_items ) : ?>
<?php endif; ?>
<td class="product-name">
<?php
@@ -154,7 +159,7 @@ wc_print_notices();
foreach ( $totals as $key => $total ) {
?>
<tr>
<th scope="row" <?php echo ( $allow_remove_item ) ? 'colspan="2"' : ''; ?>><?php echo esc_html( $total['label'] ); ?></th>
<th scope="row" <?php echo ( $allow_remove_items ) ? 'colspan="2"' : ''; ?>><?php echo esc_html( $total['label'] ); ?></th>
<td><?php echo wp_kses_post( $total['value'] ); ?></td>
</tr>
<?php

View File

@@ -588,6 +588,17 @@ function wcs_can_items_be_removed( $subscription ) {
return apply_filters( 'wcs_can_items_be_removed', $allow_remove, $subscription );
}
/**
* Checks if the user can be granted the permission to remove a particular line item from the subscription.
*
* @param WC_Order_item $item An instance of a WC_Order_item object
* @param WC_Subscription $subscription An instance of a WC_Subscription object
* @since 2.2.15
*/
function wcs_can_item_be_removed( $item, $subscription ) {
return apply_filters( 'wcs_can_item_be_removed', true, $item, $subscription );
}
/**
* Get the Product ID for an order's line item (only the product ID, not the variation ID, even if the order item
* is for a variation).

View File

@@ -5,8 +5,10 @@
* Description: Sell products and services with recurring payments in your WooCommerce Store.
* Author: Prospress Inc.
* Author URI: http://prospress.com/
* Version: 2.2.13
* Version: 2.2.15
*
* WC requires at least: 2.5
* WC tested up to: 3.2
* Woo: 27147:6115e6d7e297b623a169fdcf5728b224
*
* Copyright 2017 Prospress, Inc. (email : freedoms@prospress.com)
@@ -128,7 +130,7 @@ class WC_Subscriptions {
public static $plugin_file = __FILE__;
public static $version = '2.2.13';
public static $version = '2.2.15';
private static $total_subscription_count = null;
@@ -462,7 +464,7 @@ class WC_Subscriptions {
wc_clear_notices();
$url = WC()->cart->get_checkout_url();
$url = wc_get_checkout_url();
// Redirect to the same page (if the customer wouldn't be redirected to the cart) to ensure the cart widget loads correctly
} elseif ( 'yes' != get_option( 'woocommerce_cart_redirect_after_add' ) && self::is_woocommerce_pre( '2.5' ) ) {