mirror of
https://github.com/pronamic/woocommerce-subscriptions.git
synced 2025-10-07 01:54:05 +00:00
Updates to 7.6.0
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
*** WooCommerce Subscriptions Changelog ***
|
||||
|
||||
2025-06-11 - version 7.6.0
|
||||
* Update: Allow updating billing info on existing subscriptions when customer changes account details.
|
||||
* Fix: Use floats instead of integers for tax calculation in subscription switching when prices include tax.
|
||||
* Fix: Enhance checks in email templates upgrade script for WooCommerce Subscriptions core 8.3.0.
|
||||
* Dev: Refactor argument processing in run-tests.sh to add a direct check for the -w flag.
|
||||
* Fix: Undefined array key `new`
|
||||
* Fix: Ensure subscription exists before updating its last order date.
|
||||
* Fix: Prevent fatal error when the line items no longer exist in the database.
|
||||
|
||||
2025-05-20 - version 7.5.0
|
||||
* Update: Add pagination to the related orders list in the My Account > View Subscription page.
|
||||
* Fix: Infinite loop when trying to load subscription related orders meta after cache busting.
|
||||
|
@@ -673,6 +673,10 @@ class WCS_Admin_Meta_Boxes {
|
||||
foreach ( $item_data['line_subtotal'] as $line_item_id => $new_line_subtotal ) {
|
||||
$line_item = WC_Order_Factory::get_order_item( $line_item_id );
|
||||
|
||||
if ( ! $line_item ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this item's subtracted tax data hasn't been repaired, do that now.
|
||||
if ( $line_item->meta_exists( '_subtracted_base_location_tax' ) ) {
|
||||
WC_Subscriptions_Upgrader::repair_subtracted_base_taxes( $line_item->get_id() );
|
||||
|
@@ -23,10 +23,13 @@ class WC_Subscriptions_Addresses {
|
||||
|
||||
add_action( 'template_redirect', array( __CLASS__, 'maybe_restrict_edit_address_endpoint' ) );
|
||||
|
||||
add_action( 'woocommerce_after_edit_address_form_billing', __CLASS__ . '::maybe_add_edit_address_checkbox', 10 );
|
||||
add_action( 'woocommerce_after_edit_address_form_shipping', __CLASS__ . '::maybe_add_edit_address_checkbox', 10 );
|
||||
add_action( 'woocommerce_edit_account_form_fields', __CLASS__ . '::maybe_add_edit_addresses_checkbox' );
|
||||
|
||||
add_action( 'woocommerce_after_edit_address_form_billing', __CLASS__ . '::maybe_add_edit_address_checkbox' );
|
||||
add_action( 'woocommerce_after_edit_address_form_shipping', __CLASS__ . '::maybe_add_edit_address_checkbox' );
|
||||
|
||||
add_action( 'woocommerce_customer_save_address', __CLASS__ . '::maybe_update_subscription_addresses', 10, 2 );
|
||||
add_action( 'woocommerce_save_account_details', __CLASS__ . '::maybe_update_subscription_addresses_contact' );
|
||||
|
||||
add_filter( 'woocommerce_address_to_edit', __CLASS__ . '::maybe_populate_subscription_addresses', 10 );
|
||||
|
||||
@@ -111,7 +114,8 @@ class WC_Subscriptions_Addresses {
|
||||
if ( isset( $wp->query_vars['edit-address'] ) ) {
|
||||
$address_type = esc_attr( $wp->query_vars['edit-address'] );
|
||||
} else {
|
||||
$address_type = ( ! isset( $_GET['address'] ) ) ? esc_attr( $_GET['address'] ) : '';
|
||||
// No need to check nonce or sanitize address below as it'll be passed via wcs_get_address_type_to_display
|
||||
$address_type = ( isset( $_GET['address'] ) ) ? esc_attr( wp_unslash( $_GET['address'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
}
|
||||
|
||||
// translators: $1: address type (Shipping Address / Billing Address), $2: opening <strong> tag, $3: closing </strong> tag
|
||||
@@ -123,7 +127,14 @@ class WC_Subscriptions_Addresses {
|
||||
'type' => 'checkbox',
|
||||
'class' => array( 'form-row-wide' ),
|
||||
'label' => $label,
|
||||
'default' => apply_filters( 'wcs_update_all_subscriptions_addresses_checked', false ),
|
||||
/**
|
||||
* Filters whether the update all subscriptions addresses checkbox should be checked by default.
|
||||
*
|
||||
* @param bool $checked Whether the checkbox should be checked by default.
|
||||
* @since 2.3.7 Introduced.
|
||||
* @since 7.5.0 Default changed to true.
|
||||
*/
|
||||
'default' => apply_filters( 'wcs_update_all_subscriptions_addresses_checked', true ),
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -133,6 +144,99 @@ class WC_Subscriptions_Addresses {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the necessary markup on the "My Account" > "Edit Account" page for editing contact info (Name, Email)
|
||||
* to check if the customer wants to update the contact info in Billing addresses for all of their active subscriptions.
|
||||
*
|
||||
* @since 7.5.0
|
||||
*/
|
||||
public static function maybe_add_edit_addresses_checkbox() {
|
||||
global $wp;
|
||||
|
||||
// Escape early because we're not on the edit account page.
|
||||
if ( ! isset( $wp->query_vars['edit-account'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No need to render UI if user doesn't have subscriptions
|
||||
if ( ! wcs_user_has_subscription() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// translators: $1: address type (Billing Address), $2: opening <strong> tag, $3: closing </strong> tag
|
||||
$label = sprintf( esc_html__( 'Update the %1$s contact used for %2$sall%3$s future renewals of my active subscriptions', 'woocommerce-subscriptions' ), wcs_get_address_type_to_display( 'billing' ), '<strong>', '</strong>' );
|
||||
woocommerce_form_field(
|
||||
'update_all_subscriptions_billing_contact',
|
||||
array(
|
||||
'type' => 'checkbox',
|
||||
'class' => array( 'form-row-wide' ),
|
||||
'label' => $label,
|
||||
'default' => true, // Default to checked, intentionally not passed through the filter.
|
||||
)
|
||||
);
|
||||
|
||||
// Note, there is no need to add one more nonce here, we'll rely on existing save-account-details-nonce.
|
||||
}
|
||||
|
||||
/**
|
||||
* When user's contact info is successfully updated, check if the subscriber
|
||||
* has also requested to update the contact info in addresses on existing subscriptions and if so, go ahead and update
|
||||
* the addresses on the initial order for each subscription.
|
||||
*
|
||||
* @param int $user_id The ID of a user who own's the subscription (and address)
|
||||
* @since 7.5.0
|
||||
*/
|
||||
public static function maybe_update_subscription_addresses_contact( $user_id ) {
|
||||
// Verify nonce will take care of validation, and wc_get_var will check if the value is set.
|
||||
$nonce = isset( $_POST['save-account-details-nonce'] ) ? wp_unslash( $_POST['save-account-details-nonce'] ) : ( isset( $_POST['_wpnonce'] ) ? wp_unslash( $_POST['_wpnonce'] ) : '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$nonce = wc_get_var( $nonce, '' );
|
||||
if ( ! wp_verify_nonce( $nonce, 'save_account_details' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify that the current user is updating their own account
|
||||
$current_user_id = get_current_user_id();
|
||||
if ( $current_user_id <= 0 || $current_user_id !== $user_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if user has subscriptions and if they've checked the update checkbox
|
||||
if ( ! wcs_user_has_subscription( $current_user_id ) || ! isset( $_POST['update_all_subscriptions_billing_contact'] ) || wc_notice_count( 'error' ) > 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get user data directly from the user object instead of POST data
|
||||
$user = get_userdata( $user_id );
|
||||
|
||||
if ( ! $user ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the contact information from the user object
|
||||
$contact_info = array(
|
||||
'first_name' => $user->first_name,
|
||||
'last_name' => $user->last_name,
|
||||
'email' => $user->user_email,
|
||||
);
|
||||
|
||||
// Only proceed if we have contact information to update
|
||||
if ( empty( $contact_info['first_name'] ) && empty( $contact_info['last_name'] ) && empty( $contact_info['email'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all active subscriptions for the user
|
||||
$users_subscriptions = wcs_get_users_subscriptions( $user_id );
|
||||
|
||||
// Update the billing contact info for each active subscription
|
||||
foreach ( $users_subscriptions as $subscription ) {
|
||||
if ( $subscription->has_status( array( 'active', 'on-hold' ) ) ) {
|
||||
// Update the billing address with the new contact information
|
||||
wcs_set_order_address( $subscription, $contact_info, 'billing' );
|
||||
$subscription->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When a subscriber's billing or shipping address is successfully updated, check if the subscriber
|
||||
* has also requested to update the addresses on existing subscriptions and if so, go ahead and update
|
||||
@@ -147,7 +251,7 @@ class WC_Subscriptions_Addresses {
|
||||
return;
|
||||
}
|
||||
|
||||
$address_type = ( 'billing' == $address_type || 'shipping' == $address_type ) ? $address_type : '';
|
||||
$address_type = ( 'billing' === $address_type || 'shipping' === $address_type ) ? $address_type : '';
|
||||
$address_fields = WC()->countries->get_address_fields( esc_attr( $_POST[ $address_type . '_country' ] ), $address_type . '_' );
|
||||
$address = array();
|
||||
|
||||
|
@@ -2504,6 +2504,9 @@ class WC_Subscriptions_Order {
|
||||
|
||||
foreach ( $subscription_ids as $subscription_id ) {
|
||||
$subscription = wcs_get_subscription( $subscription_id );
|
||||
if ( ! $subscription ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
self::update_subscription_last_order_date_created( $subscription, $exclude_statuses );
|
||||
}
|
||||
@@ -2524,6 +2527,9 @@ class WC_Subscriptions_Order {
|
||||
}
|
||||
|
||||
$subscription = wcs_get_subscription( $object_id );
|
||||
if ( ! $subscription ) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::update_subscription_last_order_date_created( $subscription );
|
||||
}
|
||||
|
@@ -1082,6 +1082,8 @@ class WC_Subscriptions_Product {
|
||||
// Only set the meta value when the object has a meta value to workaround ambiguous default return values
|
||||
if ( $product->meta_exists( $prefixed_key ) ) {
|
||||
$meta_value = $product->get_meta( $prefixed_key, true );
|
||||
} elseif ( $product->meta_exists( $meta_key ) ) {
|
||||
$meta_value = $product->get_meta( $meta_key, true );
|
||||
}
|
||||
} elseif ( isset( $product->{$meta_key} ) ) { // WC < 3.0
|
||||
$meta_value = $product->{$meta_key};
|
||||
|
@@ -87,7 +87,7 @@ class WCS_Limiter {
|
||||
} else { // When mixed checkout is enabled
|
||||
foreach ( WC()->cart->cart_contents as $cart_item ) {
|
||||
// If the variable product is limited, it can't be purchased if it is the same variation
|
||||
if ( $product->get_parent_id() == wcs_get_objects_property( $cart_item['data'], 'parent_id' ) && $product->get_id() != $cart_item['data']->get_id() ) {
|
||||
if ( $product->get_parent_id() === $cart_item['data']->get_parent_id() && $product->get_id() !== $cart_item['data']->get_id() ) {
|
||||
$purchasable = false;
|
||||
break;
|
||||
}
|
||||
|
@@ -33,6 +33,8 @@ class WCS_Object_Data_Cache_Manager_Many_To_One extends WCS_Object_Data_Cache_Ma
|
||||
*/
|
||||
protected function trigger_update_cache_hook_from_change( $object, $key, $change ) {
|
||||
$previous_value = ! empty( $change['previous'] ) ? $change['previous'] : '';
|
||||
$this->trigger_update_cache_hook( $change['type'], $object->get_id(), $key, $change['new'], $previous_value );
|
||||
// When a meta is being deleted, the `new` key is not set.
|
||||
$new = ! empty( $change['new'] ) ? $change['new'] : '';
|
||||
$this->trigger_update_cache_hook( $change['type'], $object->get_id(), $key, $new, $previous_value );
|
||||
}
|
||||
}
|
||||
|
@@ -39,9 +39,10 @@ class WCS_Upgrade_8_3_0 {
|
||||
WCS_Upgrade_Logger::add( '8.3.0 - Updating subscription email settings.' );
|
||||
|
||||
foreach ( $settings_names as $settings_name ) {
|
||||
$option = get_option( $settings_name );
|
||||
// Cast to array helps us to avoid issues with further checks or leave the option unchanged if its format is modified by other plugins.
|
||||
$option = (array) get_option( $settings_name );
|
||||
|
||||
if ( ! $option || ( empty( $option['subject'] && empty( $option['heading'] ) ) ) ) {
|
||||
if ( empty( $option['subject'] ) && empty( $option['heading'] ) ) {
|
||||
WCS_Upgrade_Logger::add( sprintf( 'Subscription email settings not found: %s.', $settings_name ) );
|
||||
continue;
|
||||
}
|
||||
|
@@ -2235,10 +2235,10 @@ class WC_Subscriptions_Switcher {
|
||||
|
||||
if ( $order_item && ! is_bool( $order_item ) ) {
|
||||
$found_item = true;
|
||||
$item_total = (int) $order_item->get_total();
|
||||
$item_total = (float) $order_item->get_total();
|
||||
|
||||
if ( $order->get_prices_include_tax( 'edit' ) ) {
|
||||
$item_total += (int) $order_item->get_total_tax();
|
||||
$item_total += (float) $order_item->get_total_tax();
|
||||
}
|
||||
|
||||
// Remove any signup fees if necessary.
|
||||
|
11
languages/README.md
Normal file
11
languages/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Languages
|
||||
|
||||
## Generating POT
|
||||
|
||||
The generated POT template file is not included in this repository. It gets generated when building the project:
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
After the build completes, you'll find a `woocommerce-subscriptions.pot` strings file in this directory.
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
12
vendor/composer/installed.php
vendored
12
vendor/composer/installed.php
vendored
@@ -1,9 +1,9 @@
|
||||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => 'woocommerce/woocommerce-subscriptions',
|
||||
'pretty_version' => 'dev-release/7.5.0',
|
||||
'version' => 'dev-release/7.5.0',
|
||||
'reference' => '8a1aa156addc46303ccd0cf815f732235a8c2acf',
|
||||
'pretty_version' => 'dev-release/7.6.0',
|
||||
'version' => 'dev-release/7.6.0',
|
||||
'reference' => 'd10def0fd6301975f28b30ae7009dc41139e063f',
|
||||
'type' => 'wordpress-plugin',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -20,9 +20,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'woocommerce/woocommerce-subscriptions' => array(
|
||||
'pretty_version' => 'dev-release/7.5.0',
|
||||
'version' => 'dev-release/7.5.0',
|
||||
'reference' => '8a1aa156addc46303ccd0cf815f732235a8c2acf',
|
||||
'pretty_version' => 'dev-release/7.6.0',
|
||||
'version' => 'dev-release/7.6.0',
|
||||
'reference' => 'd10def0fd6301975f28b30ae7009dc41139e063f',
|
||||
'type' => 'wordpress-plugin',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* Description: Sell products and services with recurring payments in your WooCommerce Store.
|
||||
* Author: WooCommerce
|
||||
* Author URI: https://woocommerce.com/
|
||||
* Version: 7.5.0
|
||||
* Version: 7.6.0
|
||||
* Requires Plugins: woocommerce
|
||||
*
|
||||
* WC requires at least: 8.7.1
|
||||
@@ -78,7 +78,7 @@ class WC_Subscriptions {
|
||||
public static $plugin_file = __FILE__;
|
||||
|
||||
/** @var string */
|
||||
public static $version = '7.5.0'; // WRCS: DEFINED_VERSION.
|
||||
public static $version = '7.6.0'; // WRCS: DEFINED_VERSION.
|
||||
|
||||
/** @var string */
|
||||
public static $wc_minimum_supported_version = '7.7';
|
||||
|
Reference in New Issue
Block a user