mirror of
https://github.com/pronamic/woocommerce-subscriptions.git
synced 2025-10-12 20:32:55 +00:00
Updates to 5.6.0
This commit is contained in:
@@ -1,5 +1,28 @@
|
|||||||
*** Woo Subscriptions Changelog ***
|
*** Woo Subscriptions Changelog ***
|
||||||
|
|
||||||
|
2023-10-18 - version 5.6.0
|
||||||
|
* Add: Introduce the "Subscription Relationship" column under the Orders list admin page when HPOS is enabled.
|
||||||
|
* Add: Use admin theme color and the correct WooCommerce colors.
|
||||||
|
* Fix: Resolved an issue that caused subscriptions to go on-hold when a customer fails or abandons an early renewal order payment.
|
||||||
|
* Fix: Resolved an issue that caused subscriptions with an unpaid early renewal order to be incorrectly considered as needing payment.
|
||||||
|
* Fix: When HPOS is enabled, make the orders_by_type_query filter box work in the WooCommerce orders screen.
|
||||||
|
* Fix: Ensure renewal orders paid via the Block Checkout are correctly linked to their subscription.
|
||||||
|
* Fix: Resolved an issue that caused paying for failed/pending parent orders that include Product Add-ons to not calculate the correct total.
|
||||||
|
* Fix: Ensure the order needs processing transient is deleted when a subscription order (eg renewal) is created. Fixes issues with renewal orders going straight to a completed status.
|
||||||
|
* Fix: Store the correct subscription start date in postmeta and ordermeta when HPOS and data syncing is being used.
|
||||||
|
* Fix: When HPOS is enabled, deleting a customer will now delete their subscriptions.
|
||||||
|
* Fix: Missing styles on the Edit Subscription page when HPOS is enabled.
|
||||||
|
* Fix: Resolve an issue that would cause additional subscriptions to be created when completing a switch via the Block Checkout.
|
||||||
|
* Fix: Resolve an issue that would cause 3rd party plugin edit product fields with the show_if_variable-subscription class to be incorrectly hidden.
|
||||||
|
* Fix: Allow gateways to execute action on payment method deletion before updating the subscription.
|
||||||
|
* Fix: Ensure subscriptions have a date created that correctly accounts for the site's timezone. Fixes issues with subscriptions having a date created double the site's UTC offset.
|
||||||
|
* Fix: When HPOS is enabled, fix quick-editing the subscription statuses on the admin list table.
|
||||||
|
* Dev: PHP 8.2: Fix "Creation of dynamic property" warnings.
|
||||||
|
* Dev: PHP 8.2: Fix "Automatic conversion of false to array is deprecated" warnings.
|
||||||
|
* Dev: PHP warnings from using debug_backtrace().
|
||||||
|
* Dev: Updated subscriptions-core to 6.4.0
|
||||||
|
* Dev: Updated the hooks for Checkout Blocks, replacing the deprecated `woocommerce_blocks_checkout_` prefixed hooks with `woocommerce_store_api_checkout`.
|
||||||
|
|
||||||
2023-09-21 - version 5.5.0
|
2023-09-21 - version 5.5.0
|
||||||
* Tweak - Use admin theme color in selectors.
|
* Tweak - Use admin theme color in selectors.
|
||||||
* Tweak - Change plugin name to Woo Subscriptions.
|
* Tweak - Change plugin name to Woo Subscriptions.
|
||||||
|
@@ -52,6 +52,11 @@ class WCS_Report_Dashboard {
|
|||||||
|
|
||||||
$cached_results = get_transient( strtolower( __CLASS__ ) );
|
$cached_results = get_transient( strtolower( __CLASS__ ) );
|
||||||
|
|
||||||
|
// Set a default value for cached results for PHP 8.2+ compatibility.
|
||||||
|
if ( empty( $cached_results ) ) {
|
||||||
|
$cached_results = [];
|
||||||
|
}
|
||||||
|
|
||||||
// Subscription signups this month
|
// Subscription signups this month
|
||||||
$query = $wpdb->prepare(
|
$query = $wpdb->prepare(
|
||||||
"SELECT COUNT(DISTINCT wcsubs.ID) AS count
|
"SELECT COUNT(DISTINCT wcsubs.ID) AS count
|
||||||
@@ -69,7 +74,7 @@ class WCS_Report_Dashboard {
|
|||||||
|
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = $wpdb->get_var( apply_filters( 'woocommerce_subscription_dashboard_status_widget_signup_query', $query ) );
|
$cached_results[ $query_hash ] = $wpdb->get_var( apply_filters( 'woocommerce_subscription_dashboard_status_widget_signup_query', $query ) );
|
||||||
$update_cache = true;
|
$update_cache = true;
|
||||||
@@ -128,7 +133,7 @@ class WCS_Report_Dashboard {
|
|||||||
|
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = $wpdb->get_var( apply_filters( 'woocommerce_subscription_dashboard_status_widget_renewal_query', $query ) );
|
$cached_results[ $query_hash ] = $wpdb->get_var( apply_filters( 'woocommerce_subscription_dashboard_status_widget_renewal_query', $query ) );
|
||||||
$update_cache = true;
|
$update_cache = true;
|
||||||
@@ -162,7 +167,7 @@ class WCS_Report_Dashboard {
|
|||||||
|
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = $wpdb->get_var( apply_filters( 'woocommerce_subscription_dashboard_status_widget_renewal_revenue_query', $query ) );
|
$cached_results[ $query_hash ] = $wpdb->get_var( apply_filters( 'woocommerce_subscription_dashboard_status_widget_renewal_revenue_query', $query ) );
|
||||||
$update_cache = true;
|
$update_cache = true;
|
||||||
@@ -185,7 +190,7 @@ class WCS_Report_Dashboard {
|
|||||||
|
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = $wpdb->get_var( apply_filters( 'woocommerce_subscription_dashboard_status_widget_cancellation_query', $query ) );
|
$cached_results[ $query_hash ] = $wpdb->get_var( apply_filters( 'woocommerce_subscription_dashboard_status_widget_cancellation_query', $query ) );
|
||||||
$update_cache = true;
|
$update_cache = true;
|
||||||
|
@@ -239,7 +239,12 @@ class WCS_Report_Subscription_By_Customer extends WP_List_Table {
|
|||||||
$cached_results = get_transient( strtolower( __CLASS__ ) );
|
$cached_results = get_transient( strtolower( __CLASS__ ) );
|
||||||
$query_hash = md5( $total_query );
|
$query_hash = md5( $total_query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
// Set a default value for cached results for PHP 8.2+ compatibility.
|
||||||
|
if ( empty( $cached_results ) ) {
|
||||||
|
$cached_results = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
// Enable big selects for reports
|
// Enable big selects for reports
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_customer_total_data', $wpdb->get_row( $total_query ) );
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_customer_total_data', $wpdb->get_row( $total_query ) );
|
||||||
@@ -268,7 +273,7 @@ class WCS_Report_Subscription_By_Customer extends WP_List_Table {
|
|||||||
|
|
||||||
$query_hash = md5( $renewal_switch_total_query );
|
$query_hash = md5( $renewal_switch_total_query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
// Enable big selects for reports
|
// Enable big selects for reports
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_customer_total_renewal_switch_data', $wpdb->get_row( $renewal_switch_total_query ) );
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_customer_total_renewal_switch_data', $wpdb->get_row( $renewal_switch_total_query ) );
|
||||||
|
@@ -161,7 +161,12 @@ class WCS_Report_Subscription_By_Product extends WP_List_Table {
|
|||||||
$cached_results = get_transient( strtolower( __CLASS__ ) );
|
$cached_results = get_transient( strtolower( __CLASS__ ) );
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
// Set a default value for cached results for PHP 8.2+ compatibility.
|
||||||
|
if ( empty( $cached_results ) ) {
|
||||||
|
$cached_results = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_product_data', $wpdb->get_results( $query, OBJECT_K ), $args );
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_product_data', $wpdb->get_results( $query, OBJECT_K ), $args );
|
||||||
set_transient( strtolower( __CLASS__ ), $cached_results, WEEK_IN_SECONDS );
|
set_transient( strtolower( __CLASS__ ), $cached_results, WEEK_IN_SECONDS );
|
||||||
@@ -214,7 +219,7 @@ class WCS_Report_Subscription_By_Product extends WP_List_Table {
|
|||||||
|
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_product_lifetime_value_data', $wpdb->get_results( $query, OBJECT_K ), $args );
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_product_lifetime_value_data', $wpdb->get_results( $query, OBJECT_K ), $args );
|
||||||
set_transient( strtolower( __CLASS__ ), $cached_results, WEEK_IN_SECONDS );
|
set_transient( strtolower( __CLASS__ ), $cached_results, WEEK_IN_SECONDS );
|
||||||
|
@@ -268,6 +268,11 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
|
|
||||||
$cached_results = get_transient( strtolower( get_class( $this ) ) );
|
$cached_results = get_transient( strtolower( get_class( $this ) ) );
|
||||||
|
|
||||||
|
// Set a default value for cached results for PHP 8.2+ compatibility.
|
||||||
|
if ( empty( $cached_results ) ) {
|
||||||
|
$cached_results = [];
|
||||||
|
}
|
||||||
|
|
||||||
// Check if we need to update the cache with the query results from the figures generated by get_order_report_data().
|
// Check if we need to update the cache with the query results from the figures generated by get_order_report_data().
|
||||||
foreach ( array( 'new_subscriptions' => 'new_subscriptions', 'renewals' => 'renewal', 'resubscribes' => 'resubscribe', 'switches' => 'switch' ) as $report => $property_key ) { // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
foreach ( array( 'new_subscriptions' => 'new_subscriptions', 'renewals' => 'renewal', 'resubscribes' => 'resubscribe', 'switches' => 'switch' ) as $report => $property_key ) { // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound
|
||||||
$query_hash = $this->report_data->{"{$report}_query_hash"};
|
$query_hash = $this->report_data->{"{$report}_query_hash"};
|
||||||
@@ -314,7 +319,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
|
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_sign_up_data', (array) $wpdb->get_results( $query ), $args );
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_sign_up_data', (array) $wpdb->get_results( $query ), $args );
|
||||||
$update_cache = true;
|
$update_cache = true;
|
||||||
@@ -379,7 +384,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
|
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_subscriber_count_data', (array) $wpdb->get_results( $query ), $args );
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_subscriber_count_data', (array) $wpdb->get_results( $query ), $args );
|
||||||
$update_cache = true;
|
$update_cache = true;
|
||||||
@@ -408,7 +413,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
|
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_cancel_count_data', (array) $wpdb->get_results( $query ), $args );
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_cancel_count_data', (array) $wpdb->get_results( $query ), $args );
|
||||||
$update_cache = true;
|
$update_cache = true;
|
||||||
@@ -438,7 +443,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
|
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_ended_count_data', (array) $wpdb->get_results( $query ), $args );
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_ended_count_data', (array) $wpdb->get_results( $query ), $args );
|
||||||
$update_cache = true;
|
$update_cache = true;
|
||||||
|
@@ -17,6 +17,8 @@ class WCS_Report_Upcoming_Recurring_Revenue extends WC_Admin_Report {
|
|||||||
|
|
||||||
public $order_ids_recurring_totals = null;
|
public $order_ids_recurring_totals = null;
|
||||||
|
|
||||||
|
public $average_sales = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the legend for the main chart sidebar
|
* Get the legend for the main chart sidebar
|
||||||
* @return array
|
* @return array
|
||||||
@@ -161,7 +163,12 @@ class WCS_Report_Upcoming_Recurring_Revenue extends WC_Admin_Report {
|
|||||||
$cached_results = get_transient( strtolower( get_class( $this ) ) );
|
$cached_results = get_transient( strtolower( get_class( $this ) ) );
|
||||||
$query_hash = md5( $base_query );
|
$query_hash = md5( $base_query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
// Set a default value for cached results for PHP 8.2+ compatibility.
|
||||||
|
if ( empty( $cached_results ) ) {
|
||||||
|
$cached_results = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_upcoming_recurring_revenue_data', $wpdb->get_results( $base_query, OBJECT_K ), $args );
|
$cached_results[ $query_hash ] = apply_filters( 'wcs_reports_upcoming_recurring_revenue_data', $wpdb->get_results( $base_query, OBJECT_K ), $args );
|
||||||
set_transient( strtolower( get_class( $this ) ), $cached_results, WEEK_IN_SECONDS );
|
set_transient( strtolower( get_class( $this ) ), $cached_results, WEEK_IN_SECONDS );
|
||||||
|
@@ -14,6 +14,13 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
|
|
||||||
class WCS_Cart_Early_Renewal extends WCS_Cart_Renewal {
|
class WCS_Cart_Early_Renewal extends WCS_Cart_Renewal {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The meta key used to store whether the subscription dates have been updated for an early renewal.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const SUBSCRIPTION_DATES_UPDATED_META_KEY = '_wcs_early_renewal_subscription_dates_updated';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bootstraps the class and hooks required actions & filters.
|
* Bootstraps the class and hooks required actions & filters.
|
||||||
*/
|
*/
|
||||||
@@ -26,27 +33,14 @@ class WCS_Cart_Early_Renewal extends WCS_Cart_Renewal {
|
|||||||
add_action( 'template_redirect', array( $this, 'maybe_setup_cart' ), 100 );
|
add_action( 'template_redirect', array( $this, 'maybe_setup_cart' ), 100 );
|
||||||
|
|
||||||
add_action( 'woocommerce_checkout_create_order', array( $this, 'copy_subscription_meta_to_order' ), 90 );
|
add_action( 'woocommerce_checkout_create_order', array( $this, 'copy_subscription_meta_to_order' ), 90 );
|
||||||
|
|
||||||
// Record early renewal payments.
|
// Record early renewal payments.
|
||||||
if ( wcs_is_woocommerce_pre( '3.0' ) ) {
|
add_action( 'woocommerce_checkout_create_order', array( $this, 'add_early_renewal_metadata_to_order' ), 100, 2 );
|
||||||
add_action( 'woocommerce_checkout_order_processed', array( $this, 'maybe_record_early_renewal' ), 100, 2 );
|
|
||||||
} else {
|
|
||||||
add_action( 'woocommerce_checkout_create_order', array( $this, 'add_early_renewal_metadata_to_order' ), 100, 2 );
|
|
||||||
if ( class_exists( 'Automattic\WooCommerce\Blocks\Package' ) ) {
|
|
||||||
if ( version_compare( \Automattic\WooCommerce\Blocks\Package::get_version(), '7.2.0', '>=' ) ) {
|
|
||||||
add_action( 'woocommerce_store_api_checkout_update_order_meta', array( $this, 'add_early_renewal_metadata_to_order' ), 100, 1 );
|
|
||||||
} elseif ( version_compare( \Automattic\WooCommerce\Blocks\Package::get_version(), '6.3.0', '>=' ) ) {
|
|
||||||
add_action( 'woocommerce_blocks_checkout_update_order_meta', array( $this, 'add_early_renewal_metadata_to_order' ), 100, 1 );
|
|
||||||
} else {
|
|
||||||
add_action( '__experimental_woocommerce_blocks_checkout_update_order_meta', array( $this, 'add_early_renewal_metadata_to_order' ), 100, 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process early renewal by making sure subscription's dates are updated.
|
add_action( 'woocommerce_store_api_checkout_update_order_meta', array( $this, 'add_early_renewal_metadata_to_order' ), 100, 1 );
|
||||||
add_action( 'subscriptions_activated_for_order', array( $this, 'maybe_update_dates' ) );
|
|
||||||
|
|
||||||
// Handle early renewal orders that are cancelled.
|
// Handle early renewal orders status changes.
|
||||||
add_action( 'woocommerce_order_status_cancelled', array( $this, 'maybe_reactivate_subscription' ), 100, 2 );
|
add_action( 'woocommerce_order_status_changed', array( $this, 'maybe_record_subscription_payment' ), 5, 4 );
|
||||||
|
|
||||||
// Add a subscription note to record early renewal order.
|
// Add a subscription note to record early renewal order.
|
||||||
add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'add_note_to_record_early_renewal' ) );
|
add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'add_note_to_record_early_renewal' ) );
|
||||||
@@ -55,7 +49,7 @@ class WCS_Cart_Early_Renewal extends WCS_Cart_Renewal {
|
|||||||
add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'set_cart_item_renewal_order_data' ), 5 );
|
add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'set_cart_item_renewal_order_data' ), 5 );
|
||||||
|
|
||||||
// Allow customers to cancel early renewal orders from their my account page.
|
// Allow customers to cancel early renewal orders from their my account page.
|
||||||
add_filter( 'woocommerce_my_account_my_orders_actions', array( $this, 'add_cancel_order_action' ), 15, 2 );
|
add_filter( 'woocommerce_my_account_my_orders_actions', array( $this, 'filter_early_renewal_order_actions' ), 15, 2 );
|
||||||
add_action( 'wp_loaded', array( $this, 'allow_early_renewal_order_cancellation' ), 10, 3 );
|
add_action( 'wp_loaded', array( $this, 'allow_early_renewal_order_cancellation' ), 10, 3 );
|
||||||
|
|
||||||
// Handles early renew of password-protected products.
|
// Handles early renew of password-protected products.
|
||||||
@@ -128,37 +122,6 @@ class WCS_Cart_Early_Renewal extends WCS_Cart_Renewal {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Records an early renewal against order created on checkout (only for WooCommerce < 3.0).
|
|
||||||
*
|
|
||||||
* @param int $order_id The post_id of a shop_order post/WC_Order object.
|
|
||||||
* @param array $posted_data The data posted on checkout.
|
|
||||||
* @since 2.3.0
|
|
||||||
*/
|
|
||||||
public function maybe_record_early_renewal( $order_id, $posted_data ) {
|
|
||||||
if ( ! wcs_is_woocommerce_pre( '3.0' ) ) {
|
|
||||||
wcs_deprecated_function( __METHOD__, '2.0', 'WCS_Cart_Early_Renewal::add_early_renewal_metadata_to_order( $order, $posted_data )' );
|
|
||||||
}
|
|
||||||
|
|
||||||
$cart_item = $this->cart_contains();
|
|
||||||
|
|
||||||
if ( ! $cart_item ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the subscription.
|
|
||||||
$subscription = wcs_get_subscription( $cart_item[ $this->cart_item_key ]['subscription_id'] );
|
|
||||||
|
|
||||||
// Mark this order as a renewal.
|
|
||||||
update_post_meta( $order_id, '_subscription_renewal', $subscription->get_id() );
|
|
||||||
|
|
||||||
// Mark this order as an early renewal.
|
|
||||||
update_post_meta( $order_id, '_subscription_renewal_early', $subscription->get_id() );
|
|
||||||
|
|
||||||
// Put the subscription on hold until payment is complete.
|
|
||||||
$subscription->update_status( 'on-hold', _x( 'Customer requested to renew early:', 'used in order note as reason for why subscription status changed', 'woocommerce-subscriptions' ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the metadata from the subscription to the order created on checkout.
|
* Copies the metadata from the subscription to the order created on checkout.
|
||||||
*
|
*
|
||||||
@@ -188,8 +151,8 @@ class WCS_Cart_Early_Renewal extends WCS_Cart_Renewal {
|
|||||||
* @since 2.3.0
|
* @since 2.3.0
|
||||||
*/
|
*/
|
||||||
public function add_early_renewal_metadata_to_order( $order, $data = array() ) {
|
public function add_early_renewal_metadata_to_order( $order, $data = array() ) {
|
||||||
|
|
||||||
$cart_item = $this->cart_contains();
|
$cart_item = $this->cart_contains();
|
||||||
|
|
||||||
if ( ! $cart_item ) {
|
if ( ! $cart_item ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -202,65 +165,6 @@ class WCS_Cart_Early_Renewal extends WCS_Cart_Renewal {
|
|||||||
|
|
||||||
// Mark this order as an early renewal.
|
// Mark this order as an early renewal.
|
||||||
$order->update_meta_data( '_subscription_renewal_early', $subscription->get_id() );
|
$order->update_meta_data( '_subscription_renewal_early', $subscription->get_id() );
|
||||||
|
|
||||||
// Put the subscription on hold until payment is complete.
|
|
||||||
$subscription->update_status( 'on-hold', _x( 'Customer requested to renew early:', 'used in order note as reason for why subscription status changed', 'woocommerce-subscriptions' ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the next payment and end dates on a subscription to extend them and account
|
|
||||||
* for early renewal.
|
|
||||||
*
|
|
||||||
* @param int $order_id The WC Order ID which contains an early renewal.
|
|
||||||
* @since 2.3.0
|
|
||||||
*/
|
|
||||||
public function maybe_update_dates( $order_id ) {
|
|
||||||
|
|
||||||
$order = wc_get_order( $order_id );
|
|
||||||
|
|
||||||
if ( ! $order || ! wcs_order_contains_early_renewal( $order ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$subscription_id = wcs_get_objects_property( $order, 'subscription_renewal_early' );
|
|
||||||
$subscription = wcs_get_subscription( $subscription_id );
|
|
||||||
|
|
||||||
if ( ! $subscription ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wcs_update_dates_after_early_renewal( $subscription, $order );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reactivates an on hold subscription when an early renewal order
|
|
||||||
* is cancelled by the user.
|
|
||||||
*
|
|
||||||
* @param int $order_id The WC Order ID which contains an early renewal.
|
|
||||||
* @since 2.3.0
|
|
||||||
*/
|
|
||||||
public function maybe_reactivate_subscription( $order_id ) {
|
|
||||||
|
|
||||||
// Get the order and make sure we have one.
|
|
||||||
$order = wc_get_order( $order_id );
|
|
||||||
|
|
||||||
if ( wcs_order_contains_early_renewal( $order ) ) {
|
|
||||||
|
|
||||||
// Get the subscription and make sure we have one.
|
|
||||||
$subscription = wcs_get_subscription( wcs_get_objects_property( $order, 'subscription_renewal_early' ) );
|
|
||||||
|
|
||||||
if ( ! $subscription || ! $subscription->has_status( 'on-hold' ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the next payment date isn't in the past.
|
|
||||||
if ( strtotime( $subscription->get_date( 'next_payment' ) ) < time() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reactivate the subscription.
|
|
||||||
$subscription->update_status( 'active' );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -346,19 +250,33 @@ class WCS_Cart_Early_Renewal extends WCS_Cart_Renewal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure customers can cancel early renewal orders.
|
* Filters the list of actions customers can make on an order from their My Account page.
|
||||||
*
|
*
|
||||||
* Renewal orders are usually not cancellable because @see WCS_Cart_Renewal::filter_my_account_my_orders_actions() prevents it.
|
* Unlike standard renewal orders early renewal orders can be cancelled and cannot be paid.
|
||||||
* In the case of early renewals, the customer has opted for early renewal and so should be able to cancel it in order to reactivate their subscription.
|
*
|
||||||
|
* This function is intended to run after @see WCS_Cart_Renewal::filter_my_account_my_orders_actions() which removes the cancel and pay option.
|
||||||
|
*
|
||||||
|
* @param array $actions A list of actions customers can make on an order from their My Account page.
|
||||||
|
* @param WC_Order $order The order.
|
||||||
*
|
*
|
||||||
* @param array $actions A list of actions customers can make on an order from their My Account page
|
|
||||||
* @param WC_Order $order The order the list of actions relate to.
|
|
||||||
* @return array $actions
|
* @return array $actions
|
||||||
* @since 2.3.0
|
|
||||||
*/
|
*/
|
||||||
public static function add_cancel_order_action( $actions, $order ) {
|
public static function filter_early_renewal_order_actions( $actions, $order ) {
|
||||||
|
|
||||||
if ( ! isset( $actions['cancel'] ) && wcs_order_contains_early_renewal( $order ) && in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ) ) {
|
// Bail if the order can already be cancelled and cannot be paid.
|
||||||
|
if ( isset( $actions['cancel'] ) && ! isset( $actions['pay'] ) ) {
|
||||||
|
return $actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! wcs_order_contains_early_renewal( $order ) ) {
|
||||||
|
return $actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Early renewal orders that failed, cannot be paid. The customer must retry by following the early renewal flow again.
|
||||||
|
unset( $actions['pay'] );
|
||||||
|
|
||||||
|
// Add the cancel action back if the order has a status that allows it to be cancelled.
|
||||||
|
if ( ! isset( $actions['cancel'] ) && in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ) ) {
|
||||||
$redirect = wc_get_page_permalink( 'myaccount' );
|
$redirect = wc_get_page_permalink( 'myaccount' );
|
||||||
|
|
||||||
// Redirect the customer back to the view subscription page if that is where they cancel the order from.
|
// Redirect the customer back to the view subscription page if that is where they cancel the order from.
|
||||||
@@ -384,7 +302,7 @@ class WCS_Cart_Early_Renewal extends WCS_Cart_Renewal {
|
|||||||
* Allow customers to cancel early renewal orders from their account page.
|
* Allow customers to cancel early renewal orders from their account page.
|
||||||
*
|
*
|
||||||
* Renewal orders are usually not cancellable because @see WC_Subscriptions_Renewal_Order::prevent_cancelling_renewal_orders() prevents the request from being processed.
|
* Renewal orders are usually not cancellable because @see WC_Subscriptions_Renewal_Order::prevent_cancelling_renewal_orders() prevents the request from being processed.
|
||||||
* In the case of early renewals, the customer has opted for early renewal and so should be able to cancel it in order to reactivate their subscription.
|
* In the case of early renewals, the customer has opted for early renewal and so should be able to cancel it.
|
||||||
*
|
*
|
||||||
* @since 2.3.0
|
* @since 2.3.0
|
||||||
*/
|
*/
|
||||||
@@ -519,4 +437,194 @@ class WCS_Cart_Early_Renewal extends WCS_Cart_Renewal {
|
|||||||
|
|
||||||
return $order_meta;
|
return $order_meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records successful and unsuccessful subscription payments for early renewal orders.
|
||||||
|
*
|
||||||
|
* @param int $order_id The ID of the order transitioned.
|
||||||
|
* @param string $old_status The old order's status.
|
||||||
|
* @param string $new_status The new order's status.
|
||||||
|
* @param WC_Order $order The order object. Optional. Older versions of WC didn't provide this. Falls back to the order_id if not provided.
|
||||||
|
*/
|
||||||
|
public function maybe_record_subscription_payment( $order_id, $old_status, $new_status, $order = null ) {
|
||||||
|
|
||||||
|
// We're only interested in order status transitions that involve payment.
|
||||||
|
if ( in_array( $new_status, [ 'cancelled', 'refunded' ] ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $order ) {
|
||||||
|
$order = wc_get_order( $order_id );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only continue if this is an early renewal order.
|
||||||
|
if ( ! $order || ! wcs_order_contains_early_renewal( $order ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent the default renewal order status transitions from updating the subscription status.
|
||||||
|
// Early renewal orders are optional and should not affect the subscription status.
|
||||||
|
if ( remove_action( 'woocommerce_order_status_changed', 'WC_Subscriptions_Renewal_Order::maybe_record_subscription_payment', 10 ) ) {
|
||||||
|
|
||||||
|
// Add a callback to reattach the function which handles renewal order payment status transitions, after the current request has finished.
|
||||||
|
add_action( 'woocommerce_order_status_changed', array( $this, 'reattach_renewal_order_status_handling' ), 11 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're only interested in processing order transitions from a status that required payment.
|
||||||
|
if ( ! in_array( $old_status, apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'on-hold', 'failed' ), $order ) ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$subscription = wcs_get_subscription( absint( $order->get_meta( '_subscription_renewal_early' ) ) );
|
||||||
|
|
||||||
|
// Payment success - if payment was successful and dates haven't been updated for this order, update the subscription dates and store meta to prevent dates being updated multiple times for the same order.
|
||||||
|
if ( $subscription && $order->is_paid() && ! $order->meta_exists( self::SUBSCRIPTION_DATES_UPDATED_META_KEY ) ) {
|
||||||
|
wcs_update_dates_after_early_renewal( $subscription, $order );
|
||||||
|
|
||||||
|
$order->update_meta_data( self::SUBSCRIPTION_DATES_UPDATED_META_KEY, wc_bool_to_string( true ) );
|
||||||
|
$order->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reattaches the function which handles renewal order payment status transitions.
|
||||||
|
*
|
||||||
|
* The default renewal order status transition is detached when processing an early renewal
|
||||||
|
* order but needs to be reattached otherwise any renewal order status updates later in
|
||||||
|
* this request will not be processed.
|
||||||
|
*
|
||||||
|
* @see self::maybe_record_subscription_payment()
|
||||||
|
*
|
||||||
|
* @since 5.2.0
|
||||||
|
*/
|
||||||
|
public function reattach_renewal_order_status_handling() {
|
||||||
|
add_action( 'woocommerce_order_status_changed', 'WC_Subscriptions_Renewal_Order::maybe_record_subscription_payment', 10, 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEPRECATED FUNCTIONS.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the next payment and end dates on a subscription to extend them and account
|
||||||
|
* for early renewal.
|
||||||
|
*
|
||||||
|
* @deprecated 5.2.0
|
||||||
|
*
|
||||||
|
* @param int $order_id The WC Order ID which contains an early renewal.
|
||||||
|
* @since 2.3.0
|
||||||
|
*/
|
||||||
|
public function maybe_update_dates( $order_id ) {
|
||||||
|
wcs_deprecated_function( __METHOD__, '5.2.0' );
|
||||||
|
|
||||||
|
$order = wc_get_order( $order_id );
|
||||||
|
|
||||||
|
if ( ! $order || ! wcs_order_contains_early_renewal( $order ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$subscription_id = wcs_get_objects_property( $order, 'subscription_renewal_early' );
|
||||||
|
$subscription = wcs_get_subscription( $subscription_id );
|
||||||
|
|
||||||
|
if ( ! $subscription ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wcs_update_dates_after_early_renewal( $subscription, $order );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reactivates an on hold subscription when an early renewal order
|
||||||
|
* is cancelled by the user.
|
||||||
|
*
|
||||||
|
* @param int $order_id The WC Order ID which contains an early renewal.
|
||||||
|
* @since 2.3.0
|
||||||
|
*/
|
||||||
|
public function maybe_reactivate_subscription( $order_id ) {
|
||||||
|
wcs_deprecated_function( __METHOD__, '5.2.0' );
|
||||||
|
|
||||||
|
// Get the order and make sure we have one.
|
||||||
|
$order = wc_get_order( $order_id );
|
||||||
|
|
||||||
|
if ( wcs_order_contains_early_renewal( $order ) ) {
|
||||||
|
|
||||||
|
// Get the subscription and make sure we have one.
|
||||||
|
$subscription = wcs_get_subscription( wcs_get_objects_property( $order, 'subscription_renewal_early' ) );
|
||||||
|
|
||||||
|
if ( ! $subscription || ! $subscription->has_status( 'on-hold' ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the next payment date isn't in the past.
|
||||||
|
if ( strtotime( $subscription->get_date( 'next_payment' ) ) < time() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reactivate the subscription.
|
||||||
|
$subscription->update_status( 'active' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records an early renewal against order created on checkout (only for WooCommerce < 3.0).
|
||||||
|
*
|
||||||
|
* @param int $order_id The post_id of a shop_order post/WC_Order object.
|
||||||
|
* @param array $posted_data The data posted on checkout.
|
||||||
|
* @since 2.3.0
|
||||||
|
*/
|
||||||
|
public function maybe_record_early_renewal( $order_id, $posted_data ) {
|
||||||
|
wcs_deprecated_function( __METHOD__, '5.2.0', 'WCS_Cart_Early_Renewal::add_early_renewal_metadata_to_order( $order, $posted_data )' );
|
||||||
|
|
||||||
|
$cart_item = $this->cart_contains();
|
||||||
|
|
||||||
|
if ( ! $cart_item ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the subscription.
|
||||||
|
$subscription = wcs_get_subscription( $cart_item[ $this->cart_item_key ]['subscription_id'] );
|
||||||
|
|
||||||
|
// Mark this order as a renewal.
|
||||||
|
update_post_meta( $order_id, '_subscription_renewal', $subscription->get_id() );
|
||||||
|
|
||||||
|
// Mark this order as an early renewal.
|
||||||
|
update_post_meta( $order_id, '_subscription_renewal_early', $subscription->get_id() );
|
||||||
|
|
||||||
|
// Put the subscription on hold until payment is complete.
|
||||||
|
$subscription->update_status( 'on-hold', _x( 'Customer requested to renew early:', 'used in order note as reason for why subscription status changed', 'woocommerce-subscriptions' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure customers can cancel early renewal orders.
|
||||||
|
*
|
||||||
|
* Renewal orders are usually not cancellable because @see WCS_Cart_Renewal::filter_my_account_my_orders_actions() prevents it.
|
||||||
|
* In the case of early renewals, the customer has opted for early renewal and so should be able to cancel it.
|
||||||
|
*
|
||||||
|
* @param array $actions A list of actions customers can make on an order from their My Account page
|
||||||
|
* @param WC_Order $order The order the list of actions relate to.
|
||||||
|
* @return array $actions
|
||||||
|
* @since 2.3.0
|
||||||
|
*/
|
||||||
|
public static function add_cancel_order_action( $actions, $order ) {
|
||||||
|
wcs_deprecated_function( __METHOD__, '5.6.0', __CLASS__ . '::filter_early_renewal_order_actions()' );
|
||||||
|
|
||||||
|
if ( ! isset( $actions['cancel'] ) && wcs_order_contains_early_renewal( $order ) && in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ) ) {
|
||||||
|
$redirect = wc_get_page_permalink( 'myaccount' );
|
||||||
|
|
||||||
|
// Redirect the customer back to the view subscription page if that is where they cancel the order from.
|
||||||
|
if ( wcs_is_view_subscription_page() ) {
|
||||||
|
global $wp;
|
||||||
|
$subscription = wcs_get_subscription( $wp->query_vars['view-subscription'] );
|
||||||
|
|
||||||
|
if ( wcs_is_subscription( $subscription ) ) {
|
||||||
|
$redirect = $subscription->get_view_order_url();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$actions['cancel'] = array(
|
||||||
|
'url' => $order->get_cancel_order_url( $redirect ),
|
||||||
|
'name' => __( 'Cancel', 'woocommerce-subscriptions' ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $actions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,11 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
|
|
||||||
class WCS_Retry_Admin {
|
class WCS_Retry_Admin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string The ID of the setting to enable/disable the retry system.
|
||||||
|
*/
|
||||||
|
public $setting_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
|
@@ -54,15 +54,7 @@ class WC_Subscriptions_Switcher {
|
|||||||
add_action( 'woocommerce_checkout_update_order_meta', array( __CLASS__, 'add_order_meta' ), 10, 2 );
|
add_action( 'woocommerce_checkout_update_order_meta', array( __CLASS__, 'add_order_meta' ), 10, 2 );
|
||||||
|
|
||||||
// Same as above for WooCommerce Blocks.
|
// Same as above for WooCommerce Blocks.
|
||||||
if ( class_exists( 'Automattic\WooCommerce\Blocks\Package' ) ) {
|
add_action( 'woocommerce_store_api_checkout_update_order_meta', array( __CLASS__, 'add_order_meta' ), 10, 1 );
|
||||||
if ( version_compare( \Automattic\WooCommerce\Blocks\Package::get_version(), '7.2.0', '>=' ) ) {
|
|
||||||
add_action( 'woocommerce_store_api_checkout_update_order_meta', array( __CLASS__, 'add_order_meta' ), 10, 1 );
|
|
||||||
} elseif ( version_compare( \Automattic\WooCommerce\Blocks\Package::get_version(), '6.3.0', '>=' ) ) {
|
|
||||||
add_action( 'woocommerce_blocks_checkout_update_order_meta', array( __CLASS__, 'add_order_meta' ), 10, 1 );
|
|
||||||
} else {
|
|
||||||
add_action( '__experimental_woocommerce_blocks_checkout_update_order_meta', array( __CLASS__, 'add_order_meta' ), 10, 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't allow switching to the same product
|
// Don't allow switching to the same product
|
||||||
add_filter( 'woocommerce_add_to_cart_validation', array( __CLASS__, 'validate_switch_request' ), 10, 4 );
|
add_filter( 'woocommerce_add_to_cart_validation', array( __CLASS__, 'validate_switch_request' ), 10, 4 );
|
||||||
@@ -1224,14 +1216,14 @@ class WC_Subscriptions_Switcher {
|
|||||||
* @return bool|array Returns cart items that modify subscription contents, or false if no such items exist.
|
* @return bool|array Returns cart items that modify subscription contents, or false if no such items exist.
|
||||||
*/
|
*/
|
||||||
public static function cart_contains_switches( $item_action = 'switch' ) {
|
public static function cart_contains_switches( $item_action = 'switch' ) {
|
||||||
$subscription_switches = false;
|
$subscription_switches = [];
|
||||||
|
|
||||||
if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || false == DOING_AJAX ) ) {
|
if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || false == DOING_AJAX ) ) {
|
||||||
return $subscription_switches;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! isset( WC()->cart ) ) {
|
if ( ! isset( WC()->cart ) ) {
|
||||||
return $subscription_switches;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use WC()->cart->cart_contents instead of WC()->cart->get_cart() to prevent recursion caused when get_cart_from_session() is called too early ref: https://github.com/woocommerce/woocommerce/commit/1f3365f2066b1e9d7e84aca7b1d7e89a6989c213
|
// We use WC()->cart->cart_contents instead of WC()->cart->get_cart() to prevent recursion caused when get_cart_from_session() is called too early ref: https://github.com/woocommerce/woocommerce/commit/1f3365f2066b1e9d7e84aca7b1d7e89a6989c213
|
||||||
@@ -1263,7 +1255,7 @@ class WC_Subscriptions_Switcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $subscription_switches;
|
return ! empty( $subscription_switches ) ? $subscription_switches : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -106,6 +106,12 @@ class WCS_Switch_Cart_Item {
|
|||||||
*/
|
*/
|
||||||
public $switch_type;
|
public $switch_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the last order was a switch and was a fully reduced pre-paid term.
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $is_switch_after_fully_reduced_prepaid_term;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
File diff suppressed because it is too large
Load Diff
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
@@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
|
|||||||
|
|
||||||
require_once __DIR__ . '/composer/autoload_real.php';
|
require_once __DIR__ . '/composer/autoload_real.php';
|
||||||
|
|
||||||
return ComposerAutoloaderInit06e38849db55c37d72e7daef1d52dece::getLoader();
|
return ComposerAutoloaderInit59c7b20d3f201de5581a0bc09b6c2289::getLoader();
|
||||||
|
8
vendor/composer/autoload_real.php
vendored
8
vendor/composer/autoload_real.php
vendored
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// autoload_real.php @generated by Composer
|
// autoload_real.php @generated by Composer
|
||||||
|
|
||||||
class ComposerAutoloaderInit06e38849db55c37d72e7daef1d52dece
|
class ComposerAutoloaderInit59c7b20d3f201de5581a0bc09b6c2289
|
||||||
{
|
{
|
||||||
private static $loader;
|
private static $loader;
|
||||||
|
|
||||||
@@ -24,12 +24,12 @@ class ComposerAutoloaderInit06e38849db55c37d72e7daef1d52dece
|
|||||||
|
|
||||||
require __DIR__ . '/platform_check.php';
|
require __DIR__ . '/platform_check.php';
|
||||||
|
|
||||||
spl_autoload_register(array('ComposerAutoloaderInit06e38849db55c37d72e7daef1d52dece', 'loadClassLoader'), true, true);
|
spl_autoload_register(array('ComposerAutoloaderInit59c7b20d3f201de5581a0bc09b6c2289', '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('ComposerAutoloaderInit06e38849db55c37d72e7daef1d52dece', 'loadClassLoader'));
|
spl_autoload_unregister(array('ComposerAutoloaderInit59c7b20d3f201de5581a0bc09b6c2289', 'loadClassLoader'));
|
||||||
|
|
||||||
require __DIR__ . '/autoload_static.php';
|
require __DIR__ . '/autoload_static.php';
|
||||||
call_user_func(\Composer\Autoload\ComposerStaticInit06e38849db55c37d72e7daef1d52dece::getInitializer($loader));
|
call_user_func(\Composer\Autoload\ComposerStaticInit59c7b20d3f201de5581a0bc09b6c2289::getInitializer($loader));
|
||||||
|
|
||||||
$loader->register(true);
|
$loader->register(true);
|
||||||
|
|
||||||
|
8
vendor/composer/autoload_static.php
vendored
8
vendor/composer/autoload_static.php
vendored
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
namespace Composer\Autoload;
|
namespace Composer\Autoload;
|
||||||
|
|
||||||
class ComposerStaticInit06e38849db55c37d72e7daef1d52dece
|
class ComposerStaticInit59c7b20d3f201de5581a0bc09b6c2289
|
||||||
{
|
{
|
||||||
public static $prefixLengthsPsr4 = array (
|
public static $prefixLengthsPsr4 = array (
|
||||||
'C' =>
|
'C' =>
|
||||||
@@ -129,9 +129,9 @@ class ComposerStaticInit06e38849db55c37d72e7daef1d52dece
|
|||||||
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 = ComposerStaticInit06e38849db55c37d72e7daef1d52dece::$prefixLengthsPsr4;
|
$loader->prefixLengthsPsr4 = ComposerStaticInit59c7b20d3f201de5581a0bc09b6c2289::$prefixLengthsPsr4;
|
||||||
$loader->prefixDirsPsr4 = ComposerStaticInit06e38849db55c37d72e7daef1d52dece::$prefixDirsPsr4;
|
$loader->prefixDirsPsr4 = ComposerStaticInit59c7b20d3f201de5581a0bc09b6c2289::$prefixDirsPsr4;
|
||||||
$loader->classMap = ComposerStaticInit06e38849db55c37d72e7daef1d52dece::$classMap;
|
$loader->classMap = ComposerStaticInit59c7b20d3f201de5581a0bc09b6c2289::$classMap;
|
||||||
|
|
||||||
}, null, ClassLoader::class);
|
}, null, ClassLoader::class);
|
||||||
}
|
}
|
||||||
|
14
vendor/composer/installed.json
vendored
14
vendor/composer/installed.json
vendored
@@ -156,17 +156,17 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "woocommerce/subscriptions-core",
|
"name": "woocommerce/subscriptions-core",
|
||||||
"version": "6.2.0",
|
"version": "6.4.0",
|
||||||
"version_normalized": "6.2.0.0",
|
"version_normalized": "6.4.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": "47cfe92d60239d1b8b12a5f640a3772b0e4e1272"
|
"reference": "a94c9aab6d47f32461974ed09a4d3cad590f25b0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Automattic/woocommerce-subscriptions-core/zipball/47cfe92d60239d1b8b12a5f640a3772b0e4e1272",
|
"url": "https://api.github.com/repos/Automattic/woocommerce-subscriptions-core/zipball/a94c9aab6d47f32461974ed09a4d3cad590f25b0",
|
||||||
"reference": "47cfe92d60239d1b8b12a5f640a3772b0e4e1272",
|
"reference": "a94c9aab6d47f32461974ed09a4d3cad590f25b0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -179,7 +179,7 @@
|
|||||||
"woocommerce/woocommerce-sniffs": "0.1.0",
|
"woocommerce/woocommerce-sniffs": "0.1.0",
|
||||||
"yoast/phpunit-polyfills": "1.0.3"
|
"yoast/phpunit-polyfills": "1.0.3"
|
||||||
},
|
},
|
||||||
"time": "2023-08-10T23:43:48+00:00",
|
"time": "2023-10-18T03:32:50+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.2.0",
|
"source": "https://github.com/Automattic/woocommerce-subscriptions-core/tree/6.4.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"
|
||||||
|
18
vendor/composer/installed.php
vendored
18
vendor/composer/installed.php
vendored
@@ -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/5.5.0',
|
'pretty_version' => 'dev-release/5.6.0',
|
||||||
'version' => 'dev-release/5.5.0',
|
'version' => 'dev-release/5.6.0',
|
||||||
'reference' => '9c5944431141ef588b010663dd1539c41d12cf69',
|
'reference' => '434da4e19c4fde75e431338fa82595320bd5b6c1',
|
||||||
'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.2.0',
|
'pretty_version' => '6.4.0',
|
||||||
'version' => '6.2.0.0',
|
'version' => '6.4.0.0',
|
||||||
'reference' => '47cfe92d60239d1b8b12a5f640a3772b0e4e1272',
|
'reference' => 'a94c9aab6d47f32461974ed09a4d3cad590f25b0',
|
||||||
'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/5.5.0',
|
'pretty_version' => 'dev-release/5.6.0',
|
||||||
'version' => 'dev-release/5.5.0',
|
'version' => 'dev-release/5.6.0',
|
||||||
'reference' => '9c5944431141ef588b010663dd1539c41d12cf69',
|
'reference' => '434da4e19c4fde75e431338fa82595320bd5b6c1',
|
||||||
'type' => 'wordpress-plugin',
|
'type' => 'wordpress-plugin',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
|
@@ -27,7 +27,7 @@ ul {
|
|||||||
}
|
}
|
||||||
.wcs-badge {
|
.wcs-badge {
|
||||||
position: relative;
|
position: relative;
|
||||||
background: #9c5d90;
|
background: #7F54B3;
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
padding-top: 150px;
|
padding-top: 150px;
|
||||||
height: 52px;
|
height: 52px;
|
||||||
@@ -35,7 +35,7 @@ ul {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #ddc8d9;
|
color: #fff;
|
||||||
margin: 5px 0 0 0;
|
margin: 5px 0 0 0;
|
||||||
-webkit-box-shadow: 0 1px 3px rgba( 0, 0, 0, 0.2 );
|
-webkit-box-shadow: 0 1px 3px rgba( 0, 0, 0, 0.2 );
|
||||||
box-shadow: 0 1px 3px rgba( 0, 0, 0, 0.2 );
|
box-shadow: 0 1px 3px rgba( 0, 0, 0, 0.2 );
|
||||||
@@ -92,44 +92,10 @@ ul {
|
|||||||
}
|
}
|
||||||
.woocommerce-message {
|
.woocommerce-message {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-left-color: #cc99c2 !important;
|
border-left-color: #7F54B3 !important;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-message a.button-primary,
|
|
||||||
p.woocommerce-actions a.button-primary,
|
|
||||||
.woocommerce-message a.button-primary:focus,
|
|
||||||
p.woocommerce-actions a.button-primary:focus,
|
|
||||||
.woocommerce-message a.button-primary:active,
|
|
||||||
p.woocommerce-actions a.button-primary:active {
|
|
||||||
background: #b366a4;
|
|
||||||
border-color: #b366a4;
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba( 255, 255, 255, 0.25 ),
|
|
||||||
0 1px 0 rgba( 0, 0, 0, 0.15 );
|
|
||||||
box-shadow: inset 0 1px 0 rgba( 255, 255, 255, 0.25 ),
|
|
||||||
0 1px 0 rgba( 0, 0, 0, 0.15 );
|
|
||||||
text-shadow: 0 -1px 1px #b366a4, 1px 0 1px #b366a4, 0 1px 1px #b366a4,
|
|
||||||
-1px 0 1px #b366a4;
|
|
||||||
color: #fff;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.woocommerce-message a.button-primary:hover,
|
|
||||||
p.woocommerce-actions a.button-primary:hover {
|
|
||||||
background: #bb77ae;
|
|
||||||
border-color: #aa559a;
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba( 255, 255, 255, 0.25 ),
|
|
||||||
0 1px 0 rgba( 0, 0, 0, 0.15 );
|
|
||||||
box-shadow: inset 0 1px 0 rgba( 255, 255, 255, 0.25 ),
|
|
||||||
0 1px 0 rgba( 0, 0, 0, 0.15 );
|
|
||||||
}
|
|
||||||
|
|
||||||
.woocommerce-message a.button-primary:active,
|
|
||||||
p.woocommerce-actions a.button-primary:active {
|
|
||||||
background: #aa559a;
|
|
||||||
border-color: #aa559a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.woocommerce-message a.skip,
|
.woocommerce-message a.skip,
|
||||||
p.woocommerce-actions a.skip {
|
p.woocommerce-actions a.skip {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
|
@@ -2,19 +2,6 @@
|
|||||||
.woocommerce-subscriptions-activated p a.button-primary {
|
.woocommerce-subscriptions-activated p a.button-primary {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.woocommerce-subscriptions-activated a.button-primary:hover {
|
|
||||||
background: #bb77ae;
|
|
||||||
border-color: #aa559a;
|
|
||||||
-webkit-box-shadow: inset 0 1px 0 rgba( 255, 255, 255, 0.25 ),
|
|
||||||
0 1px 0 rgba( 0, 0, 0, 0.15 );
|
|
||||||
box-shadow: inset 0 1px 0 rgba( 255, 255, 255, 0.25 ),
|
|
||||||
0 1px 0 rgba( 0, 0, 0, 0.15 );
|
|
||||||
}
|
|
||||||
.woocommerce-subscriptions-activated a.button-primary:active,
|
|
||||||
.woocommerce-subscriptions-activated a.button-primary:active {
|
|
||||||
background: #aa559a;
|
|
||||||
border-color: #aa559a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Subscriptions Admin Page */
|
/* Subscriptions Admin Page */
|
||||||
.woocommerce_page_wc-orders--shop_subscription .tablenav input,
|
.woocommerce_page_wc-orders--shop_subscription .tablenav input,
|
||||||
@@ -314,6 +301,25 @@ a.close-subscriptions-search {
|
|||||||
width: auto !important;
|
width: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wc_input_subscription_payment_sync +.select2,
|
||||||
|
.wc_input_subscription_length +.select2,
|
||||||
|
#_subscription_limit +.select2 {
|
||||||
|
min-width: 180px;
|
||||||
|
width: 80% !important;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc_input_subscription_period + .select2,
|
||||||
|
.wc_input_subscription_trial_period + .select2 {
|
||||||
|
width: 30.75% !important;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc_input_subscription_period_interval + .select2 {
|
||||||
|
margin-right: 3.8%;
|
||||||
|
width: 30.75% !important;
|
||||||
|
}
|
||||||
|
|
||||||
.variable_subscription_sync p._subscription_payment_sync_field {
|
.variable_subscription_sync p._subscription_payment_sync_field {
|
||||||
padding-left: 0 !important;
|
padding-left: 0 !important;
|
||||||
}
|
}
|
||||||
@@ -360,7 +366,32 @@ a.close-subscriptions-search {
|
|||||||
.wc_input_subscription_period_interval {
|
.wc_input_subscription_period_interval {
|
||||||
max-width: 33%;
|
max-width: 33%;
|
||||||
float: left;
|
float: left;
|
||||||
|
margin-right: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#variable_product_options .select2 {
|
||||||
|
margin: 2px 2px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#variable_product_options
|
||||||
|
.select2-container
|
||||||
|
.select2-selection--single {
|
||||||
|
min-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#variable_product_options
|
||||||
|
.select2-container
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__rendered {
|
||||||
|
line-height: 36px;
|
||||||
|
}
|
||||||
|
#variable_product_options
|
||||||
|
.select2-container
|
||||||
|
.select2-selection--single
|
||||||
|
.select2-selection__arrow {
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
.variable_subscription_pricing_2_3 .wc_input_subscription_price {
|
.variable_subscription_pricing_2_3 .wc_input_subscription_price {
|
||||||
clear: left;
|
clear: left;
|
||||||
}
|
}
|
||||||
@@ -735,7 +766,7 @@ table.wp-list-table .subscription_renewal_order::after {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
content: '\e018';
|
content: '\e018';
|
||||||
color: #a46497;
|
color: var(--wp-admin-theme-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
table.wc_gateways .renewals .tips {
|
table.wc_gateways .renewals .tips {
|
||||||
|
@@ -40,21 +40,14 @@ jQuery( function ( $ ) {
|
|||||||
'hide_if_variable-subscription'
|
'hide_if_variable-subscription'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
var product_type = $( 'select#product-type' ).val();
|
||||||
* WC core will hide and show product specific fields in show_and_hide_panels(), however that function only runs on specific events, but not
|
|
||||||
* when variations are added or loaded. To make sure our subscription-related fields aren't shown by default when a variation is added, we set
|
|
||||||
* subscription pricing elements "base" cases here.
|
|
||||||
*
|
|
||||||
* Note: show() being called on the 'hide_if_' fields and vice versa is intentional. All fields are set in their inverse state first, and
|
|
||||||
* then shown/hidden by product type afterwards.
|
|
||||||
*/
|
|
||||||
$( '.hide_if_variable-subscription' ).show();
|
|
||||||
$( '.show_if_variable-subscription' ).hide();
|
|
||||||
|
|
||||||
if ( $( 'select#product-type' ).val() == 'variable-subscription' ) {
|
if ( 'variable-subscription' === product_type ) {
|
||||||
|
// Hide and show subscription fields when variable subscription is selected
|
||||||
$( 'input#_downloadable' ).prop( 'checked', false );
|
$( 'input#_downloadable' ).prop( 'checked', false );
|
||||||
$( 'input#_virtual' ).prop( 'checked', false );
|
$( 'input#_virtual' ).prop( 'checked', false );
|
||||||
|
|
||||||
|
// Variable subscriptions inherit fields from variable products.
|
||||||
$( '.show_if_variable' ).show();
|
$( '.show_if_variable' ).show();
|
||||||
$( '.hide_if_variable' ).hide();
|
$( '.hide_if_variable' ).hide();
|
||||||
$( '.show_if_variable-subscription' ).show();
|
$( '.show_if_variable-subscription' ).show();
|
||||||
@@ -67,14 +60,7 @@ jQuery( function ( $ ) {
|
|||||||
.addClass( 'form-row-full' )
|
.addClass( 'form-row-full' )
|
||||||
.removeClass( 'form-row-last' );
|
.removeClass( 'form-row-last' );
|
||||||
} else {
|
} else {
|
||||||
if ( 'variable' === $( 'select#product-type' ).val() ) {
|
if ( 'subscription' === product_type ) {
|
||||||
$( '.show_if_variable-subscription' ).hide();
|
|
||||||
$( '.show_if_variable' ).show();
|
|
||||||
$( '.hide_if_variable' ).hide();
|
|
||||||
$.showOrHideStockFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 'subscription' === $( 'select#product-type' ).val() ) {
|
|
||||||
$( '.show_if_subscription' ).show();
|
$( '.show_if_subscription' ).show();
|
||||||
$( '.hide_if_subscription' ).hide();
|
$( '.hide_if_subscription' ).hide();
|
||||||
}
|
}
|
||||||
|
@@ -1 +1 @@
|
|||||||
<?php return array('dependencies' => array('wc-blocks-checkout', 'wc-price-format', 'wc-settings', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '7855adadf2c3ec0499bc9a7854758556');
|
<?php return array('dependencies' => array('wc-blocks-checkout', 'wc-price-format', 'wc-settings', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '5386ce4810e198e8d50d4e1491067c34');
|
@@ -14,7 +14,7 @@ Object(l.__)("Recurring total every 2nd %1$s","woocommerce-subscriptions"),n);ca
|
|||||||
/* Translators: %1$s is week, month, year */
|
/* Translators: %1$s is week, month, year */
|
||||||
Object(l.__)("Recurring total every 3rd %1$s","woocommerce-subscriptions"),n);default:return Object(l.sprintf)(
|
Object(l.__)("Recurring total every 3rd %1$s","woocommerce-subscriptions"),n);default:return Object(l.sprintf)(
|
||||||
/* Translators: %1$d is number of weeks, months, days, years. %2$s is week, month, year */
|
/* Translators: %1$d is number of weeks, months, days, years. %2$s is week, month, year */
|
||||||
Object(l.__)("Recurring total every %1$dth %2$s","woocommerce-subscriptions"),t,n)}}({billingInterval:n,billingPeriod:c});return Object(r.createElement)(i.TotalsItem,{className:"wcs-recurring-totals-panel__title",currency:t,label:u,value:a,description:Object(r.createElement)(f,{nextPaymentDate:o,subscriptionLength:s,billingInterval:n,billingPeriod:c})})},j=function(e){var t,n,c,o=e.subscription,s=e.needsShipping,u=e.calculatedShipping,p=o.totals,b=o.billing_interval,m=o.billing_period,f=o.next_payment_date,j=o.subscription_length,w=o.shipping_rates;if(!f)return null;var v=null==w||null===(t=w[0])||void 0===t||null===(n=t.shipping_rates)||void 0===n||null===(c=n.find((function(e){return e.selected})))||void 0===c?void 0:c.name,y=Object(a.getCurrencyFromPriceResponse)(p);return Object(r.createElement)("div",{className:"wcs-recurring-totals-panel"},Object(r.createElement)(O,{billingInterval:b,billingPeriod:m,nextPaymentDate:f,subscriptionLength:j,totals:parseInt(p.total_price,10),currency:y}),Object(r.createElement)(i.Panel,{className:"wcs-recurring-totals-panel__details",initialOpen:!1,title:Object(l.__)("Details","woocommerce-subscriptions")},Object(r.createElement)(i.TotalsWrapper,null,Object(r.createElement)(i.Subtotal,{currency:y,values:p}),Object(r.createElement)(d,{currency:y,values:p})),Object(r.createElement)(i.TotalsWrapper,null,Object(r.createElement)(_,{currency:y,needsShipping:s,calculatedShipping:u,values:p,selectedRate:v})),!g&&Object(r.createElement)(i.TotalsWrapper,null,Object(r.createElement)(i.TotalsTaxes,{currency:y,values:p})),Object(r.createElement)(i.TotalsWrapper,null,Object(r.createElement)(i.TotalsItem,{className:"wcs-recurring-totals-panel__details-total",currency:y,label:Object(l.__)("Total","woocommerce-subscriptions"),value:parseInt(p.total_price,10)}))))},w=function(e){var t=e.extensions,n=e.cart,c=t.subscriptions,i=n.cartNeedsShipping,o=n.cartHasCalculatedShipping;return c&&0!==c.length?c.map((function(e){var t=e.key,n=s()(e,["key"]);return Object(r.createElement)(j,{subscription:n,needsShipping:i,calculatedShipping:o,key:t})})):null},v=function(e){var t=e.extensions,n=e.collapsible,c=e.collapse,i=e.showItems,o=e.noResultsMessage,l=e.renderOption,a=e.components,u=t.subscriptions,p=void 0===u?[]:u,b=a.ShippingRatesControlPackage,m=Object(r.useMemo)((function(){return Object.values(p).map((function(e){return e.shipping_rates})).filter(Boolean).flat()}),[p]),g=Object(r.useMemo)((function(){return 1<m.length||c}),[m.length,c]),d=Object(r.useMemo)((function(){return 1<m.length||i}),[m.length,i]);return m.map((function(e){var t=e.package_id,c=s()(e,["package_id"]);return Object(r.createElement)(b,{key:t,packageId:t,packageData:c,collapsible:n,collapse:g,showItems:d,noResultsMessage:o,renderOption:l})}))};n(9),Object(c.registerPlugin)("woocommerce-subscriptions",{render:function(){return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(i.ExperimentalOrderShippingPackages,null,Object(r.createElement)(v,null)),Object(r.createElement)(i.ExperimentalOrderMeta,null,Object(r.createElement)(w,null)))},scope:"woocommerce-checkout"}),Object(i.__experimentalRegisterCheckoutFilters)("woocommerce-subscriptions",{totalLabel:function(e,t){var n=t.subscriptions;return 0<(null==n?void 0:n.length)?Object(l.__)("Total due today","woocommerce-subscriptions"):e},subtotalPriceFormat:function(e,t){var n=t.subscriptions;if(null!=n&&n.billing_period&&null!=n&&n.billing_interval){var r=n.billing_interval,c=n.subscription_length;return m({subscriptionLength:c,billingInterval:r})?b(n,1===c?// translators: the word used to describe billing frequency, e.g. "fo1" 1 day or "for" 1 month.
|
Object(l.__)("Recurring total every %1$dth %2$s","woocommerce-subscriptions"),t,n)}}({billingInterval:n,billingPeriod:c});return Object(r.createElement)(i.TotalsItem,{className:"wcs-recurring-totals-panel__title",currency:t,label:u,value:a,description:Object(r.createElement)(f,{nextPaymentDate:o,subscriptionLength:s,billingInterval:n,billingPeriod:c})})},j=function(e){var t,n,c,o=e.subscription,s=e.needsShipping,u=e.calculatedShipping,p=o.totals,b=o.billing_interval,m=o.billing_period,f=o.next_payment_date,j=o.subscription_length,w=o.shipping_rates;if(!f)return null;var v=null==w||null===(t=w[0])||void 0===t||null===(n=t.shipping_rates)||void 0===n||null===(c=n.find((function(e){return e.selected})))||void 0===c?void 0:c.name,y=Object(a.getCurrencyFromPriceResponse)(p);return Object(r.createElement)("div",{className:"wcs-recurring-totals-panel"},Object(r.createElement)(O,{billingInterval:b,billingPeriod:m,nextPaymentDate:f,subscriptionLength:j,totals:parseInt(p.total_price,10),currency:y}),Object(r.createElement)(i.Panel,{className:"wcs-recurring-totals-panel__details",initialOpen:!1,title:Object(l.__)("Details","woocommerce-subscriptions")},Object(r.createElement)(i.TotalsWrapper,null,Object(r.createElement)(i.Subtotal,{currency:y,values:p}),Object(r.createElement)(d,{currency:y,values:p})),Object(r.createElement)(i.TotalsWrapper,null,Object(r.createElement)(_,{currency:y,needsShipping:s,calculatedShipping:u,values:p,selectedRate:v})),!g&&Object(r.createElement)(i.TotalsWrapper,null,Object(r.createElement)(i.TotalsTaxes,{currency:y,values:p})),Object(r.createElement)(i.TotalsWrapper,null,Object(r.createElement)(i.TotalsItem,{className:"wcs-recurring-totals-panel__details-total",currency:y,label:Object(l.__)("Total","woocommerce-subscriptions"),value:parseInt(p.total_price,10)}))))},w=function(e){var t=e.extensions,n=e.cart,c=t.subscriptions,i=n.cartNeedsShipping,o=n.cartHasCalculatedShipping;return c&&0!==c.length?c.map((function(e){var t=e.key,n=s()(e,["key"]);return Object(r.createElement)(j,{subscription:n,needsShipping:i,calculatedShipping:o,key:t})})):null},v=function(e){var t=e.extensions,n=e.collapsible,c=e.collapse,i=e.showItems,o=e.noResultsMessage,l=e.renderOption,a=e.components,u=t.subscriptions,p=void 0===u?[]:u,b=a.ShippingRatesControlPackage,m=Object(r.useMemo)((function(){return Object.values(p).map((function(e){return e.shipping_rates})).filter(Boolean).flat()}),[p]),g=Object(r.useMemo)((function(){return 1<m.length||c}),[m.length,c]),d=Object(r.useMemo)((function(){return 1<m.length||i}),[m.length,i]);return m.map((function(e){var t=e.package_id,c=s()(e,["package_id"]);return Object(r.createElement)(b,{key:t,packageId:t,packageData:c,collapsible:n,collapse:g,showItems:d,noResultsMessage:o,renderOption:l})}))};n(9),Object(c.registerPlugin)("woocommerce-subscriptions",{render:function(){return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(i.ExperimentalOrderShippingPackages,null,Object(r.createElement)(v,null)),Object(r.createElement)(i.ExperimentalOrderMeta,null,Object(r.createElement)(w,null)))},scope:"woocommerce-checkout"}),Object(i.registerCheckoutFilters)("woocommerce-subscriptions",{totalLabel:function(e,t){var n=t.subscriptions;return 0<(null==n?void 0:n.length)?Object(l.__)("Total due today","woocommerce-subscriptions"):e},subtotalPriceFormat:function(e,t){var n=t.subscriptions;if(null!=n&&n.billing_period&&null!=n&&n.billing_interval){var r=n.billing_interval,c=n.subscription_length;return m({subscriptionLength:c,billingInterval:r})?b(n,1===c?// translators: the word used to describe billing frequency, e.g. "fo1" 1 day or "for" 1 month.
|
||||||
Object(l.__)("for 1","woocommerce-subscriptions"):// translators: the word used to describe billing frequency, e.g. "for" 6 days or "for" 2 weeks.
|
Object(l.__)("for 1","woocommerce-subscriptions"):// translators: the word used to describe billing frequency, e.g. "for" 6 days or "for" 2 weeks.
|
||||||
Object(l.__)("for","woocommerce-subscriptions"),e):b(n,// translators: the word used to describe billing frequency, e.g. "every" 6 days or "every" 2 weeks.
|
Object(l.__)("for","woocommerce-subscriptions"),e):b(n,// translators: the word used to describe billing frequency, e.g. "every" 6 days or "every" 2 weeks.
|
||||||
Object(l.__)("every","woocommerce-subscriptions"),e)}return e},saleBadgePriceFormat:function(e,t){var n=t.subscriptions;return null!=n&&n.billing_period&&null!=n&&n.billing_interval?b(n,"/",e):e},itemName:function(e,t){var n=t.subscriptions;return null!=n&&n.is_resubscribe?Object(l.sprintf)(// translators: %s Product name.
|
Object(l.__)("every","woocommerce-subscriptions"),e)}return e},saleBadgePriceFormat:function(e,t){var n=t.subscriptions;return null!=n&&n.billing_period&&null!=n&&n.billing_interval?b(n,"/",e):e},itemName:function(e,t){var n=t.subscriptions;return null!=n&&n.is_resubscribe?Object(l.sprintf)(// translators: %s Product name.
|
||||||
|
@@ -1,5 +1,25 @@
|
|||||||
*** WooCommerce Subscriptions Core Changelog ***
|
*** WooCommerce Subscriptions Core Changelog ***
|
||||||
|
|
||||||
|
= 6.4.0 - 2023-10-18 =
|
||||||
|
* Add - Use admin theme color and the correct WooCommerce colors.
|
||||||
|
* Fix - Resolve an issue that would cause 3rd party plugin edit product fields with the show_if_variable-subscription class to be incorrectly hidden.
|
||||||
|
* Fix - Allow gateways to execute action on payment method deletion before updating the subscription.
|
||||||
|
* Fix - Ensure subscriptions have a date created that correctly accounts for the site's timezone. Fixes issues with subscriptions having a date created double the site's UTC offset.
|
||||||
|
* Fix - When HPOS is enabled, fix quick-editing the subscription statuses on the admin list table.
|
||||||
|
* Dev - Updated the hooks for Checkout Blocks, replacing the deprecated `woocommerce_blocks_checkout_` prefixed hooks with `woocommerce_store_api_checkout`.
|
||||||
|
* Dev - PHP 8.2: Fix "Creation of dynamic property" warnings.
|
||||||
|
|
||||||
|
= 6.3.0 - 2023-10-06 =
|
||||||
|
* Add - Introduce the "Subscription Relationship" column under the Orders list admin page when HPOS is enabled.
|
||||||
|
* Fix - Resolved an issue that caused subscriptions with an unpaid early renewal order to be incorrectly considered as needing payment.
|
||||||
|
* Fix - When HPOS is enabled, make the orders_by_type_query filter box work in the WooCommerce orders screen.
|
||||||
|
* Fix - Ensure renewal orders paid via the Block Checkout are correctly linked to their subscription.
|
||||||
|
* Fix - Resolved an issue that caused paying for failed/pending parent orders that include Product Add-ons to not calculate the correct total.
|
||||||
|
* Fix - Ensure the order needs processing transient is deleted when a subscription order (eg renewal) is created. Fixes issues with renewal orders going straight to a completed status.
|
||||||
|
* Fix - Store the correct subscription start date in postmeta and ordermeta when HPOS and data syncing is being used.
|
||||||
|
* Fix - When HPOS is enabled, deleting a customer will now delete their subscriptions.
|
||||||
|
* Fix - Missing styles on the Edit Subscription page when HPOS is enabled.
|
||||||
|
|
||||||
= 6.2.0 - 2023-08-10 =
|
= 6.2.0 - 2023-08-10 =
|
||||||
* Add - Introduce an updated empty state screen for the WooCommerce > Subscriptions list table.
|
* Add - Introduce an updated empty state screen for the WooCommerce > Subscriptions list table.
|
||||||
* Fix - Ensure subscription checkout and cart block integrations are loaded on store environments where WooPayments is not enabled.
|
* Fix - Ensure subscription checkout and cart block integrations are loaded on store environments where WooPayments is not enabled.
|
||||||
|
@@ -317,13 +317,13 @@ class WC_Subscriptions_Admin {
|
|||||||
<span class="wrap">
|
<span class="wrap">
|
||||||
<input type="text" id="_subscription_price" name="_subscription_price" class="wc_input_price wc_input_subscription_price" placeholder="<?php echo esc_attr_x( 'e.g. 5.90', 'example price', 'woocommerce-subscriptions' ); ?>" step="any" min="0" value="<?php echo esc_attr( wc_format_localized_price( $chosen_price ) ); ?>" />
|
<input type="text" id="_subscription_price" name="_subscription_price" class="wc_input_price wc_input_subscription_price" placeholder="<?php echo esc_attr_x( 'e.g. 5.90', 'example price', 'woocommerce-subscriptions' ); ?>" step="any" min="0" value="<?php echo esc_attr( wc_format_localized_price( $chosen_price ) ); ?>" />
|
||||||
<label for="_subscription_period_interval" class="wcs_hidden_label"><?php esc_html_e( 'Subscription interval', 'woocommerce-subscriptions' ); ?></label>
|
<label for="_subscription_period_interval" class="wcs_hidden_label"><?php esc_html_e( 'Subscription interval', 'woocommerce-subscriptions' ); ?></label>
|
||||||
<select id="_subscription_period_interval" name="_subscription_period_interval" class="wc_input_subscription_period_interval">
|
<select id="_subscription_period_interval" name="_subscription_period_interval" class="wc_input_subscription_period_interval wc-enhanced-select">
|
||||||
<?php foreach ( wcs_get_subscription_period_interval_strings() as $value => $label ) { ?>
|
<?php foreach ( wcs_get_subscription_period_interval_strings() as $value => $label ) { ?>
|
||||||
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $chosen_interval, true ); ?>><?php echo esc_html( $label ); ?></option>
|
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $chosen_interval, true ); ?>><?php echo esc_html( $label ); ?></option>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</select>
|
</select>
|
||||||
<label for="_subscription_period" class="wcs_hidden_label"><?php esc_html_e( 'Subscription period', 'woocommerce-subscriptions' ); ?></label>
|
<label for="_subscription_period" class="wcs_hidden_label"><?php esc_html_e( 'Subscription period', 'woocommerce-subscriptions' ); ?></label>
|
||||||
<select id="_subscription_period" name="_subscription_period" class="wc_input_subscription_period last" >
|
<select id="_subscription_period" name="_subscription_period" class="wc_input_subscription_period last wc-enhanced-select" >
|
||||||
<?php foreach ( wcs_get_subscription_period_strings() as $value => $label ) { ?>
|
<?php foreach ( wcs_get_subscription_period_strings() as $value => $label ) { ?>
|
||||||
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $chosen_period, true ); ?>><?php echo esc_html( $label ); ?></option>
|
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $chosen_period, true ); ?>><?php echo esc_html( $label ); ?></option>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
@@ -337,7 +337,7 @@ class WC_Subscriptions_Admin {
|
|||||||
woocommerce_wp_select(
|
woocommerce_wp_select(
|
||||||
array(
|
array(
|
||||||
'id' => '_subscription_length',
|
'id' => '_subscription_length',
|
||||||
'class' => 'wc_input_subscription_length select short',
|
'class' => 'wc_input_subscription_length select short wc-enhanced-select',
|
||||||
'label' => __( 'Expire after', 'woocommerce-subscriptions' ),
|
'label' => __( 'Expire after', 'woocommerce-subscriptions' ),
|
||||||
'options' => wcs_get_subscription_ranges( $chosen_period ),
|
'options' => wcs_get_subscription_ranges( $chosen_period ),
|
||||||
'desc_tip' => true,
|
'desc_tip' => true,
|
||||||
@@ -372,7 +372,7 @@ class WC_Subscriptions_Admin {
|
|||||||
<span class="wrap">
|
<span class="wrap">
|
||||||
<input type="text" id="_subscription_trial_length" name="_subscription_trial_length" class="wc_input_subscription_trial_length" value="<?php echo esc_attr( $chosen_trial_length ); ?>" />
|
<input type="text" id="_subscription_trial_length" name="_subscription_trial_length" class="wc_input_subscription_trial_length" value="<?php echo esc_attr( $chosen_trial_length ); ?>" />
|
||||||
<label for="_subscription_trial_period" class="wcs_hidden_label"><?php esc_html_e( 'Subscription Trial Period', 'woocommerce-subscriptions' ); ?></label>
|
<label for="_subscription_trial_period" class="wcs_hidden_label"><?php esc_html_e( 'Subscription Trial Period', 'woocommerce-subscriptions' ); ?></label>
|
||||||
<select id="_subscription_trial_period" name="_subscription_trial_period" class="wc_input_subscription_trial_period last" >
|
<select id="_subscription_trial_period" name="_subscription_trial_period" class="wc_input_subscription_trial_period last wc-enhanced-select" >
|
||||||
<?php foreach ( wcs_get_available_time_periods() as $value => $label ) { ?>
|
<?php foreach ( wcs_get_available_time_periods() as $value => $label ) { ?>
|
||||||
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $chosen_trial_period, true ); ?>><?php echo esc_html( $label ); ?></option>
|
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $chosen_trial_period, true ); ?>><?php echo esc_html( $label ); ?></option>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
@@ -943,7 +943,7 @@ class WC_Subscriptions_Admin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( $is_woocommerce_screen || 'edit-product' == $screen->id || ( isset( $_GET['page'], $_GET['tab'] ) && 'wc-reports' === $_GET['page'] && 'subscriptions' === $_GET['tab'] ) ) {
|
if ( $is_woocommerce_screen || 'edit-product' == $screen->id || ( isset( $_GET['page'], $_GET['tab'] ) && 'wc-reports' === $_GET['page'] && 'subscriptions' === $_GET['tab'] ) ) {
|
||||||
wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_Subscriptions_Core_Plugin::instance()->get_library_version() );
|
wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', [ 'wc-components' ], WC_Subscriptions_Core_Plugin::instance()->get_library_version() );
|
||||||
wp_enqueue_style( 'woocommerce_subscriptions_admin', WC_Subscriptions_Core_Plugin::instance()->get_subscriptions_core_directory_url( 'assets/css/admin.css' ), array( 'woocommerce_admin_styles' ), WC_Subscriptions_Core_Plugin::instance()->get_library_version() );
|
wp_enqueue_style( 'woocommerce_subscriptions_admin', WC_Subscriptions_Core_Plugin::instance()->get_subscriptions_core_directory_url( 'assets/css/admin.css' ), array( 'woocommerce_admin_styles' ), WC_Subscriptions_Core_Plugin::instance()->get_library_version() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1315,8 +1315,9 @@ class WCS_Admin_Post_Types {
|
|||||||
|
|
||||||
// On HPOS environments, WC expects a slightly different format for the bulk actions.
|
// On HPOS environments, WC expects a slightly different format for the bulk actions.
|
||||||
if ( $is_hpos_enabled ) {
|
if ( $is_hpos_enabled ) {
|
||||||
|
$id_key = wcs_is_woocommerce_pre( '8.1' ) ? 'order' : 'id';
|
||||||
$action_url_args = [
|
$action_url_args = [
|
||||||
'order' => [ $subscription->get_id() ],
|
$id_key => [ $subscription->get_id() ],
|
||||||
'_wpnonce' => wp_create_nonce( 'bulk-orders' ),
|
'_wpnonce' => wp_create_nonce( 'bulk-orders' ),
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
|
@@ -251,31 +251,30 @@ class WC_Subscription extends WC_Order {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the subscription has an unpaid order or renewal order (and therefore, needs payment).
|
* Checks if the subscription needs payment.
|
||||||
|
*
|
||||||
|
* A subscription requires payment if it:
|
||||||
|
* - is pending or failed,
|
||||||
|
* - has an unpaid parent order, or
|
||||||
|
* - has an unpaid order or renewal order (and therefore, needs payment)
|
||||||
*
|
*
|
||||||
* @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
|
|
||||||
* @param int $user_id The ID of the user who owns the subscriptions. Although this parameter is optional, if you have the User ID you should pass it to improve performance.
|
|
||||||
* @return bool True if the subscription has an unpaid renewal order, false if the subscription has no unpaid renewal orders.
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
|
*
|
||||||
|
* @return bool True if the subscription requires payment, otherwise false.
|
||||||
*/
|
*/
|
||||||
public function needs_payment() {
|
public function needs_payment() {
|
||||||
|
|
||||||
$needs_payment = false;
|
$needs_payment = false;
|
||||||
|
$parent_order = $this->get_parent();
|
||||||
|
|
||||||
// First check if the subscription is pending or failed or is for $0
|
// If the subscription is pending or failed and it has a total > 0, it needs payment.
|
||||||
if ( parent::needs_payment() ) {
|
if ( parent::needs_payment() ) {
|
||||||
|
|
||||||
$needs_payment = true;
|
$needs_payment = true;
|
||||||
|
} elseif ( $parent_order && ( $parent_order->needs_payment() || $parent_order->has_status( array( 'on-hold', 'cancelled' ) ) ) ) {
|
||||||
// Now make sure the parent order doesn't need payment
|
// If the subscription has an unpaid parent order, it needs payment.
|
||||||
} elseif ( ( $parent_order = $this->get_parent() ) && ( $parent_order->needs_payment() || $parent_order->has_status( array( 'on-hold', 'cancelled' ) ) ) ) {
|
|
||||||
|
|
||||||
$needs_payment = true;
|
$needs_payment = true;
|
||||||
|
|
||||||
// And finally, check that the latest order (switch or renewal) doesn't need payment
|
|
||||||
} else {
|
} else {
|
||||||
|
// Lastly, check if the last non-early renewal order needs payment.
|
||||||
$order = $this->get_last_order( 'all', array( 'renewal', 'switch' ) );
|
$order = wcs_get_last_non_early_renewal_order( $this );
|
||||||
|
|
||||||
if ( $order && ( $order->needs_payment() || $order->has_status( array( 'on-hold', 'failed', 'cancelled' ) ) ) ) {
|
if ( $order && ( $order->needs_payment() || $order->has_status( array( 'on-hold', 'failed', 'cancelled' ) ) ) ) {
|
||||||
$needs_payment = true;
|
$needs_payment = true;
|
||||||
|
@@ -24,11 +24,7 @@ class WC_Subscriptions_Checkout {
|
|||||||
add_action( 'woocommerce_checkout_order_processed', array( __CLASS__, 'process_checkout' ), 100, 2 );
|
add_action( 'woocommerce_checkout_order_processed', array( __CLASS__, 'process_checkout' ), 100, 2 );
|
||||||
|
|
||||||
// Same as above, but this is for the Checkout block.
|
// Same as above, but this is for the Checkout block.
|
||||||
if ( class_exists( 'Automattic\WooCommerce\Blocks\Package' ) && ( version_compare( \Automattic\WooCommerce\Blocks\Package::get_version(), '6.3.0', '>=' ) || \Automattic\WooCommerce\Blocks\Package::is_experimental_build() ) ) {
|
add_action( 'woocommerce_store_api_checkout_order_processed', array( __CLASS__, 'process_checkout' ), 100, 1 );
|
||||||
add_action( 'woocommerce_blocks_checkout_order_processed', array( __CLASS__, 'process_checkout' ), 100, 1 );
|
|
||||||
} else {
|
|
||||||
add_action( '__experimental_woocommerce_blocks_checkout_order_processed', array( __CLASS__, 'process_checkout' ), 100, 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some callbacks need to hooked after WC has loaded.
|
// Some callbacks need to hooked after WC has loaded.
|
||||||
add_action( 'woocommerce_loaded', array( __CLASS__, 'attach_dependant_hooks' ) );
|
add_action( 'woocommerce_loaded', array( __CLASS__, 'attach_dependant_hooks' ) );
|
||||||
|
@@ -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.2.0'; // WRCS: DEFINED_VERSION.
|
protected $library_version = '6.4.0'; // WRCS: DEFINED_VERSION.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The subscription scheduler instance.
|
* The subscription scheduler instance.
|
||||||
|
@@ -1001,7 +1001,7 @@ class WC_Subscriptions_Manager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wp_delete_post( $subscription->get_id() );
|
$subscription->delete( true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,10 @@ class WC_Subscriptions_Order {
|
|||||||
add_filter( 'manage_edit-shop_order_columns', __CLASS__ . '::add_contains_subscription_column' );
|
add_filter( 'manage_edit-shop_order_columns', __CLASS__ . '::add_contains_subscription_column' );
|
||||||
add_action( 'manage_shop_order_posts_custom_column', __CLASS__ . '::add_contains_subscription_column_content', 10, 1 );
|
add_action( 'manage_shop_order_posts_custom_column', __CLASS__ . '::add_contains_subscription_column_content', 10, 1 );
|
||||||
|
|
||||||
|
// HPOS - Add column that indicates whether an order is parent or renewal for a subscription.
|
||||||
|
add_filter( 'woocommerce_shop_order_list_table_columns', __CLASS__ . '::add_contains_subscription_column' );
|
||||||
|
add_action( 'woocommerce_shop_order_list_table_custom_column', __CLASS__ . '::add_contains_subscription_column_content_orders_table', 10, 2 );
|
||||||
|
|
||||||
// Record initial payment against the subscription & set start date based on that payment
|
// Record initial payment against the subscription & set start date based on that payment
|
||||||
add_action( 'woocommerce_order_status_changed', __CLASS__ . '::maybe_record_subscription_payment', 9, 3 );
|
add_action( 'woocommerce_order_status_changed', __CLASS__ . '::maybe_record_subscription_payment', 9, 3 );
|
||||||
|
|
||||||
@@ -44,8 +48,13 @@ class WC_Subscriptions_Order {
|
|||||||
// Add dropdown to admin orders screen to filter on order type
|
// Add dropdown to admin orders screen to filter on order type
|
||||||
add_action( 'restrict_manage_posts', __CLASS__ . '::restrict_manage_subscriptions', 50 );
|
add_action( 'restrict_manage_posts', __CLASS__ . '::restrict_manage_subscriptions', 50 );
|
||||||
|
|
||||||
|
// For HPOS - Add dropdown to admin orders screen to filter on order type.
|
||||||
|
add_action( 'woocommerce_order_list_table_restrict_manage_orders', __CLASS__ . '::restrict_manage_subscriptions_hpos' );
|
||||||
|
|
||||||
// Add filter to queries on admin orders screen to filter on order type. To avoid WC overriding our query args, we need to hook on after them on 10.
|
// Add filter to queries on admin orders screen to filter on order type. To avoid WC overriding our query args, we need to hook on after them on 10.
|
||||||
add_filter( 'request', __CLASS__ . '::orders_by_type_query', 11 );
|
add_filter( 'request', __CLASS__ . '::orders_by_type_query', 11 );
|
||||||
|
// HPOS - Add filter to queries on admin orders screen to filter on order type. Only triggered for the shop_order order type.
|
||||||
|
add_filter( 'woocommerce_shop_order_list_table_prepare_items_query_args', __CLASS__ . '::maybe_modify_orders_by_type_query_from_request', 11 );
|
||||||
|
|
||||||
// Don't display migrated order item meta on the Edit Order screen
|
// Don't display migrated order item meta on the Edit Order screen
|
||||||
add_filter( 'woocommerce_hidden_order_itemmeta', __CLASS__ . '::hide_order_itemmeta' );
|
add_filter( 'woocommerce_hidden_order_itemmeta', __CLASS__ . '::hide_order_itemmeta' );
|
||||||
@@ -411,26 +420,36 @@ class WC_Subscriptions_Order {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add column content to the WooCommerce -> Orders admin screen to indicate whether an
|
* Add column content to the WooCommerce -> Orders admin screen to indicate whether an
|
||||||
* order is a parent of a subscription, a renewal order for a subscription, or a
|
* order is a parent of a subscription, a renewal order for a subscription, or a regular order.
|
||||||
* regular order.
|
*
|
||||||
*
|
* @see add_contains_subscription_column_content_orders_table For when HPOS is enabled.
|
||||||
* @param string $column The string of the current column
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1
|
* @param string $column The string of the current column
|
||||||
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1
|
||||||
*/
|
*/
|
||||||
public static function add_contains_subscription_column_content( $column ) {
|
public static function add_contains_subscription_column_content( $column ) {
|
||||||
global $post;
|
global $post;
|
||||||
|
|
||||||
if ( 'subscription_relationship' == $column ) {
|
if ( 'subscription_relationship' === $column ) {
|
||||||
if ( wcs_order_contains_subscription( $post->ID, 'renewal' ) ) {
|
self::render_contains_subscription_column_content( $post->ID );
|
||||||
echo '<span class="subscription_renewal_order tips" data-tip="' . esc_attr__( 'Renewal Order', 'woocommerce-subscriptions' ) . '"></span>';
|
}
|
||||||
} elseif ( wcs_order_contains_subscription( $post->ID, 'resubscribe' ) ) {
|
}
|
||||||
echo '<span class="subscription_resubscribe_order tips" data-tip="' . esc_attr__( 'Resubscribe Order', 'woocommerce-subscriptions' ) . '"></span>';
|
|
||||||
} elseif ( wcs_order_contains_subscription( $post->ID, 'parent' ) ) {
|
/**
|
||||||
echo '<span class="subscription_parent_order tips" data-tip="' . esc_attr__( 'Parent Order', 'woocommerce-subscriptions' ) . '"></span>';
|
* Add column content to the WooCommerce -> Orders admin screen to indicate whether an
|
||||||
} else {
|
* order is a parent of a subscription, a renewal order for a subscription, or a regular order.
|
||||||
echo '<span class="normal_order">–</span>';
|
*
|
||||||
}
|
* @see add_contains_subscription_column_content For when HPOS is disabled.
|
||||||
|
*
|
||||||
|
* @since 6.3.0
|
||||||
|
*
|
||||||
|
* @param string $column_name Identifier for the custom column.
|
||||||
|
* @param WC_Order $order Current WooCommerce order object.
|
||||||
|
*/
|
||||||
|
public static function add_contains_subscription_column_content_orders_table( string $column_name, WC_Order $order ) {
|
||||||
|
if ( 'subscription_relationship' === $column_name ) {
|
||||||
|
self::render_contains_subscription_column_content( $order->get_id() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -708,33 +727,26 @@ class WC_Subscriptions_Order {
|
|||||||
public static function restrict_manage_subscriptions() {
|
public static function restrict_manage_subscriptions() {
|
||||||
global $typenow;
|
global $typenow;
|
||||||
|
|
||||||
if ( 'shop_order' != $typenow ) {
|
if ( 'shop_order' !== $typenow ) {
|
||||||
return;
|
return;
|
||||||
}?>
|
}
|
||||||
<select name='shop_order_subtype' id='dropdown_shop_order_subtype'>
|
|
||||||
<option value=""><?php esc_html_e( 'All orders types', 'woocommerce-subscriptions' ); ?></option>
|
|
||||||
<?php
|
|
||||||
$order_types = apply_filters( 'woocommerce_subscriptions_order_type_dropdown', array(
|
|
||||||
'original' => _x( 'Original', 'An order type', 'woocommerce-subscriptions' ),
|
|
||||||
'parent' => _x( 'Subscription Parent', 'An order type', 'woocommerce-subscriptions' ),
|
|
||||||
'renewal' => _x( 'Subscription Renewal', 'An order type', 'woocommerce-subscriptions' ),
|
|
||||||
'resubscribe' => _x( 'Subscription Resubscribe', 'An order type', 'woocommerce-subscriptions' ),
|
|
||||||
'switch' => _x( 'Subscription Switch', 'An order type', 'woocommerce-subscriptions' ),
|
|
||||||
'regular' => _x( 'Non-subscription', 'An order type', 'woocommerce-subscriptions' ),
|
|
||||||
) );
|
|
||||||
|
|
||||||
foreach ( $order_types as $order_type_key => $order_type_description ) {
|
self::render_restrict_manage_subscriptions_dropdown();
|
||||||
echo '<option value="' . esc_attr( $order_type_key ) . '"';
|
}
|
||||||
|
|
||||||
if ( isset( $_GET['shop_order_subtype'] ) && $_GET['shop_order_subtype'] ) {
|
/**
|
||||||
selected( $order_type_key, $_GET['shop_order_subtype'] );
|
* When HPOS is active, adds admin dropdown for order types to Woocommerce -> Orders screen
|
||||||
}
|
*
|
||||||
|
* @since 6.3.0
|
||||||
|
*
|
||||||
|
* @param string $order_type The order type.
|
||||||
|
*/
|
||||||
|
public static function restrict_manage_subscriptions_hpos( string $order_type ) {
|
||||||
|
if ( 'shop_order' !== $order_type ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
echo '>' . esc_html( $order_type_description ) . '</option>';
|
self::render_restrict_manage_subscriptions_dropdown();
|
||||||
}
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
<?php
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -746,64 +758,86 @@ class WC_Subscriptions_Order {
|
|||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.5
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v1.5
|
||||||
*/
|
*/
|
||||||
public static function orders_by_type_query( $vars ) {
|
public static function orders_by_type_query( $vars ) {
|
||||||
global $typenow, $wpdb;
|
global $typenow;
|
||||||
|
|
||||||
if ( 'shop_order' == $typenow && ! empty( $_GET['shop_order_subtype'] ) ) {
|
if ( 'shop_order' === $typenow ) {
|
||||||
|
return self::maybe_modify_orders_by_type_query_from_request( $vars );
|
||||||
if ( 'original' == $_GET['shop_order_subtype'] || 'regular' == $_GET['shop_order_subtype'] ) {
|
|
||||||
|
|
||||||
$vars['meta_query']['relation'] = 'AND';
|
|
||||||
|
|
||||||
$vars['meta_query'][] = array(
|
|
||||||
'key' => '_subscription_renewal',
|
|
||||||
'compare' => 'NOT EXISTS',
|
|
||||||
);
|
|
||||||
|
|
||||||
$vars['meta_query'][] = array(
|
|
||||||
'key' => '_subscription_switch',
|
|
||||||
'compare' => 'NOT EXISTS',
|
|
||||||
);
|
|
||||||
|
|
||||||
} elseif ( 'parent' == $_GET['shop_order_subtype'] ) {
|
|
||||||
|
|
||||||
$vars['post__in'] = wcs_get_subscription_orders();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
switch ( $_GET['shop_order_subtype'] ) {
|
|
||||||
case 'renewal':
|
|
||||||
$meta_key = '_subscription_renewal';
|
|
||||||
break;
|
|
||||||
case 'resubscribe':
|
|
||||||
$meta_key = '_subscription_resubscribe';
|
|
||||||
break;
|
|
||||||
case 'switch':
|
|
||||||
$meta_key = '_subscription_switch';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$meta_key = '';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$meta_key = apply_filters( 'woocommerce_subscriptions_admin_order_type_filter_meta_key', $meta_key, $_GET['shop_order_subtype'] );
|
|
||||||
|
|
||||||
if ( ! empty( $meta_key ) ) {
|
|
||||||
$vars['meta_query'][] = array(
|
|
||||||
'key' => $meta_key,
|
|
||||||
'compare' => 'EXISTS',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also exclude parent orders from non-subscription query
|
|
||||||
if ( 'regular' == $_GET['shop_order_subtype'] ) {
|
|
||||||
$vars['post__not_in'] = wcs_get_subscription_orders();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $vars;
|
return $vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the arguments to be pased to `wc_get_orders()` under the Woocommerce -> Orders screen.
|
||||||
|
*
|
||||||
|
* @since 6.3.0
|
||||||
|
*
|
||||||
|
* @param array $order_query_args Arguments to be passed to `wc_get_orders()`.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function maybe_modify_orders_by_type_query_from_request( array $order_query_args ): array {
|
||||||
|
// The order subtype selected by the user in the dropdown.
|
||||||
|
$selected_shop_order_subtype = isset( $_GET['shop_order_subtype'] ) ? wc_clean( wp_unslash( $_GET['shop_order_subtype'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||||
|
|
||||||
|
// Don't modify the query args if no order subtype was selected.
|
||||||
|
if ( empty( $selected_shop_order_subtype ) ) {
|
||||||
|
return $order_query_args;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( 'original' === $selected_shop_order_subtype || 'regular' === $selected_shop_order_subtype ) {
|
||||||
|
|
||||||
|
$order_query_args['meta_query']['relation'] = 'AND';
|
||||||
|
|
||||||
|
$order_query_args['meta_query'][] = array(
|
||||||
|
'key' => '_subscription_renewal',
|
||||||
|
'compare' => 'NOT EXISTS',
|
||||||
|
);
|
||||||
|
|
||||||
|
$order_query_args['meta_query'][] = array(
|
||||||
|
'key' => '_subscription_switch',
|
||||||
|
'compare' => 'NOT EXISTS',
|
||||||
|
);
|
||||||
|
|
||||||
|
} elseif ( 'parent' === $selected_shop_order_subtype ) {
|
||||||
|
|
||||||
|
$order_query_args['post__in'] = wcs_get_subscription_orders();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
switch ( $selected_shop_order_subtype ) {
|
||||||
|
case 'renewal':
|
||||||
|
$meta_key = '_subscription_renewal';
|
||||||
|
break;
|
||||||
|
case 'resubscribe':
|
||||||
|
$meta_key = '_subscription_resubscribe';
|
||||||
|
break;
|
||||||
|
case 'switch':
|
||||||
|
$meta_key = '_subscription_switch';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$meta_key = '';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta_key = apply_filters( 'woocommerce_subscriptions_admin_order_type_filter_meta_key', $meta_key, $selected_shop_order_subtype );
|
||||||
|
|
||||||
|
if ( ! empty( $meta_key ) ) {
|
||||||
|
$order_query_args['meta_query'][] = array(
|
||||||
|
'key' => $meta_key,
|
||||||
|
'compare' => 'EXISTS',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also exclude parent orders from non-subscription query
|
||||||
|
if ( 'regular' === $selected_shop_order_subtype ) {
|
||||||
|
$order_query_args['post__not_in'] = wcs_get_subscription_orders();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $order_query_args;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add related subscriptions below order details tables.
|
* Add related subscriptions below order details tables.
|
||||||
*
|
*
|
||||||
@@ -2280,4 +2314,64 @@ class WC_Subscriptions_Order {
|
|||||||
|
|
||||||
return $meta_value;
|
return $meta_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the HTML for the admin dropdown for order types to Woocommerce -> Orders screen.
|
||||||
|
*
|
||||||
|
* @since 6.3.0
|
||||||
|
*/
|
||||||
|
private static function render_restrict_manage_subscriptions_dropdown() {
|
||||||
|
$order_types = apply_filters(
|
||||||
|
'woocommerce_subscriptions_order_type_dropdown',
|
||||||
|
array(
|
||||||
|
'original' => _x( 'Original', 'An order type', 'woocommerce-subscriptions' ),
|
||||||
|
'parent' => _x( 'Subscription Parent', 'An order type', 'woocommerce-subscriptions' ),
|
||||||
|
'renewal' => _x( 'Subscription Renewal', 'An order type', 'woocommerce-subscriptions' ),
|
||||||
|
'resubscribe' => _x( 'Subscription Resubscribe', 'An order type', 'woocommerce-subscriptions' ),
|
||||||
|
'switch' => _x( 'Subscription Switch', 'An order type', 'woocommerce-subscriptions' ),
|
||||||
|
'regular' => _x( 'Non-subscription', 'An order type', 'woocommerce-subscriptions' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||||
|
$selected_shop_order_subtype = isset( $_GET['shop_order_subtype'] ) ? wc_clean( wp_unslash( $_GET['shop_order_subtype'] ) ) : '';
|
||||||
|
|
||||||
|
?>
|
||||||
|
<select name='shop_order_subtype' id='dropdown_shop_order_subtype'>
|
||||||
|
<option value=""><?php esc_html_e( 'All orders types', 'woocommerce-subscriptions' ); ?></option>
|
||||||
|
|
||||||
|
<?php foreach ( $order_types as $order_type_key => $order_type_description ) : ?>
|
||||||
|
<option
|
||||||
|
value="<?php echo esc_attr( $order_type_key ); ?>"
|
||||||
|
<?php selected( $selected_shop_order_subtype, $order_type_key ); ?>
|
||||||
|
>
|
||||||
|
<?php echo esc_html( $order_type_description ); ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
</select>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the contents of the "contains_subscription" column.
|
||||||
|
*
|
||||||
|
* This column indicates whether an order is a parent of a subscription,
|
||||||
|
* a renewal order for a subscription, or a regular order.
|
||||||
|
*
|
||||||
|
* @since 6.3.0
|
||||||
|
*
|
||||||
|
* @param integer $order_id The ID of the order in the current row.
|
||||||
|
*/
|
||||||
|
private static function render_contains_subscription_column_content( int $order_id ) {
|
||||||
|
if ( wcs_order_contains_subscription( $order_id, 'renewal' ) ) {
|
||||||
|
echo '<span class="subscription_renewal_order tips" data-tip="' . esc_attr__( 'Renewal Order', 'woocommerce-subscriptions' ) . '"></span>';
|
||||||
|
} elseif ( wcs_order_contains_subscription( $order_id, 'resubscribe' ) ) {
|
||||||
|
echo '<span class="subscription_resubscribe_order tips" data-tip="' . esc_attr__( 'Resubscribe Order', 'woocommerce-subscriptions' ) . '"></span>';
|
||||||
|
} elseif ( wcs_order_contains_subscription( $order_id, 'parent' ) ) {
|
||||||
|
echo '<span class="subscription_parent_order tips" data-tip="' . esc_attr__( 'Parent Order', 'woocommerce-subscriptions' ) . '"></span>';
|
||||||
|
} else {
|
||||||
|
echo '<span class="normal_order">–</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -218,6 +218,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
'css' => 'min-width:150px;',
|
'css' => 'min-width:150px;',
|
||||||
'default' => 'no',
|
'default' => 'no',
|
||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
|
'class' => 'wc-enhanced-select',
|
||||||
'options' => array(
|
'options' => array(
|
||||||
'no' => _x( 'Never (do not charge any recurring amount)', 'when to prorate first payment / subscription length', 'woocommerce-subscriptions' ),
|
'no' => _x( 'Never (do not charge any recurring amount)', 'when to prorate first payment / subscription length', 'woocommerce-subscriptions' ),
|
||||||
'recurring' => _x( 'Never (charge the full recurring amount at sign-up)', 'when to prorate first payment / subscription length', 'woocommerce-subscriptions' ),
|
'recurring' => _x( 'Never (charge the full recurring amount at sign-up)', 'when to prorate first payment / subscription length', 'woocommerce-subscriptions' ),
|
||||||
@@ -285,7 +286,7 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
woocommerce_wp_select(
|
woocommerce_wp_select(
|
||||||
array(
|
array(
|
||||||
'id' => self::$post_meta_key,
|
'id' => self::$post_meta_key,
|
||||||
'class' => 'wc_input_subscription_payment_sync select short',
|
'class' => 'wc_input_subscription_payment_sync select short wc-enhanced-select',
|
||||||
'label' => self::$sync_field_label,
|
'label' => self::$sync_field_label,
|
||||||
'options' => self::get_billing_period_ranges( $subscription_period ),
|
'options' => self::get_billing_period_ranges( $subscription_period ),
|
||||||
'description' => self::$sync_description,
|
'description' => self::$sync_description,
|
||||||
@@ -303,14 +304,14 @@ class WC_Subscriptions_Synchroniser {
|
|||||||
<span class="wrap">
|
<span class="wrap">
|
||||||
|
|
||||||
<label for="<?php echo esc_attr( self::$post_meta_key_month ); ?>" class="wcs_hidden_label"><?php esc_html_e( 'Month for Synchronisation', 'woocommerce-subscriptions' ); ?></label>
|
<label for="<?php echo esc_attr( self::$post_meta_key_month ); ?>" class="wcs_hidden_label"><?php esc_html_e( 'Month for Synchronisation', 'woocommerce-subscriptions' ); ?></label>
|
||||||
<select id="<?php echo esc_attr( self::$post_meta_key_month ); ?>" name="<?php echo esc_attr( self::$post_meta_key_month ); ?>" class="wc_input_subscription_payment_sync last" >
|
<select id="<?php echo esc_attr( self::$post_meta_key_month ); ?>" name="<?php echo esc_attr( self::$post_meta_key_month ); ?>" class="wc_input_subscription_payment_sync last wc-enhanced-select" >
|
||||||
<?php foreach ( self::get_year_sync_options() as $value => $label ) { ?>
|
<?php foreach ( self::get_year_sync_options() as $value => $label ) { ?>
|
||||||
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $payment_month, true ) ?>><?php echo esc_html( $label ); ?></option>
|
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, $payment_month, true ) ?>><?php echo esc_html( $label ); ?></option>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<?php $daysInMonth = $payment_month ? gmdate( 't', wc_string_to_timestamp( "2001-{$payment_month}-01" ) ) : 0; ?>
|
<?php $days_in_month = $payment_month ? gmdate( 't', wc_string_to_timestamp( "2001-{$payment_month}-01" ) ) : 0; ?>
|
||||||
<input type="number" id="<?php echo esc_attr( self::$post_meta_key_day ); ?>" name="<?php echo esc_attr( self::$post_meta_key_day ); ?>" class="wc_input_subscription_payment_sync" value="<?php echo esc_attr( $payment_day ); ?>" placeholder="<?php echo esc_attr_x( 'Day', 'input field placeholder for day field for annual subscriptions', 'woocommerce-subscriptions' ); ?>" step="1" min="<?php echo esc_attr( min( 1, $daysInMonth ) ); ?>" max="<?php echo esc_attr( $daysInMonth ); ?>" <?php disabled( 0, $payment_month, true ); ?> />
|
<input type="number" id="<?php echo esc_attr( self::$post_meta_key_day ); ?>" name="<?php echo esc_attr( self::$post_meta_key_day ); ?>" class="wc_input_subscription_payment_sync wc-enhanced-select" value="<?php echo esc_attr( $payment_day ); ?>" placeholder="<?php echo esc_attr_x( 'Day', 'input field placeholder for day field for annual subscriptions', 'woocommerce-subscriptions' ); ?>" step="1" min="<?php echo esc_attr( min( 1, $days_in_month ) ); ?>" max="<?php echo esc_attr( $days_in_month ); ?>" <?php disabled( 0, $payment_month, true ); ?> />
|
||||||
</span>
|
</span>
|
||||||
<?php echo wcs_help_tip( self::$sync_description_year ); ?>
|
<?php echo wcs_help_tip( self::$sync_description_year ); ?>
|
||||||
</p><?php
|
</p><?php
|
||||||
|
@@ -134,7 +134,7 @@ class WCS_Cart_Initial_Payment extends WCS_Cart_Renewal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deteremines if the cart should honor the granfathered subscription/order line item total.
|
* Determines if the cart should honor the grandfathered subscription/order line item total.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.10
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.10
|
||||||
*
|
*
|
||||||
|
@@ -35,11 +35,9 @@ class WCS_Cart_Renewal {
|
|||||||
// Remove order action buttons from the My Account page
|
// Remove order action buttons from the My Account page
|
||||||
add_filter( 'woocommerce_my_account_my_orders_actions', array( &$this, 'filter_my_account_my_orders_actions' ), 10, 2 );
|
add_filter( 'woocommerce_my_account_my_orders_actions', array( &$this, 'filter_my_account_my_orders_actions' ), 10, 2 );
|
||||||
|
|
||||||
// When a failed renewal order is paid for via checkout, make sure WC_Checkout::create_order() preserves its "failed" status until it is paid
|
|
||||||
add_filter( 'woocommerce_default_order_status', array( &$this, 'maybe_preserve_order_status' ) );
|
|
||||||
|
|
||||||
// When a failed/pending renewal order is paid for via checkout, ensure a new order isn't created due to mismatched cart hashes
|
// When a failed/pending renewal order is paid for via checkout, ensure a new order isn't created due to mismatched cart hashes
|
||||||
add_filter( 'woocommerce_create_order', array( &$this, 'update_cart_hash' ), 10, 1 );
|
add_filter( 'woocommerce_create_order', array( &$this, 'update_cart_hash' ), 10, 1 );
|
||||||
|
add_filter( 'woocommerce_order_has_status', array( &$this, 'set_renewal_order_cart_hash_on_block_checkout' ), 10, 3 );
|
||||||
|
|
||||||
// When a user is prevented from paying for a failed/pending renewal order because they aren't logged in, redirect them back after login
|
// When a user is prevented from paying for a failed/pending renewal order because they aren't logged in, redirect them back after login
|
||||||
add_filter( 'woocommerce_login_redirect', array( &$this, 'maybe_redirect_after_login' ), 10, 2 );
|
add_filter( 'woocommerce_login_redirect', array( &$this, 'maybe_redirect_after_login' ), 10, 2 );
|
||||||
@@ -93,11 +91,7 @@ class WCS_Cart_Renewal {
|
|||||||
add_action( 'woocommerce_checkout_update_order_meta', array( &$this, 'set_order_item_id' ), 10, 2 );
|
add_action( 'woocommerce_checkout_update_order_meta', array( &$this, 'set_order_item_id' ), 10, 2 );
|
||||||
|
|
||||||
// After order meta is saved, get the order line item ID for the renewal so we can update it later
|
// After order meta is saved, get the order line item ID for the renewal so we can update it later
|
||||||
if ( version_compare( \Automattic\WooCommerce\Blocks\Package::get_version(), '7.2.0', '>=' ) ) {
|
add_action( 'woocommerce_store_api_checkout_update_order_meta', array( &$this, 'set_order_item_id' ) );
|
||||||
add_action( 'woocommerce_store_api_checkout_update_order_meta', array( &$this, 'set_order_item_id' ) );
|
|
||||||
} else {
|
|
||||||
add_action( 'woocommerce_blocks_checkout_update_order_meta', array( &$this, 'set_order_item_id' ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't display cart item key meta stored above on the Edit Order screen
|
// Don't display cart item key meta stored above on the Edit Order screen
|
||||||
add_action( 'woocommerce_hidden_order_itemmeta', array( &$this, 'hidden_order_itemmeta' ), 10 );
|
add_action( 'woocommerce_hidden_order_itemmeta', array( &$this, 'hidden_order_itemmeta' ), 10 );
|
||||||
@@ -416,6 +410,10 @@ class WCS_Cart_Renewal {
|
|||||||
* Restore renewal flag when cart is reset and modify Product object with renewal order related info
|
* Restore renewal flag when cart is reset and modify Product object with renewal order related info
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
|
*
|
||||||
|
* @param array $cart_item_session_data Cart item session data.
|
||||||
|
* @param array $cart_item Cart item data.
|
||||||
|
* @param string $key Cart item key.
|
||||||
*/
|
*/
|
||||||
public function get_cart_item_from_session( $cart_item_session_data, $cart_item, $key ) {
|
public function get_cart_item_from_session( $cart_item_session_data, $cart_item, $key ) {
|
||||||
|
|
||||||
@@ -429,7 +427,23 @@ class WCS_Cart_Renewal {
|
|||||||
|
|
||||||
if ( $subscription ) {
|
if ( $subscription ) {
|
||||||
$subscription_items = $subscription->get_items();
|
$subscription_items = $subscription->get_items();
|
||||||
$item_to_renew = $subscription_items[ $cart_item_session_data[ $this->cart_item_key ]['line_item_id'] ];
|
|
||||||
|
/**
|
||||||
|
* Find the subscription or order line item that represents this cart item.
|
||||||
|
*
|
||||||
|
* If cart item data correctly records a valid line item ID, use that to find the line item.
|
||||||
|
* Otherwise, use the cart item key stored in line item meta.
|
||||||
|
*/
|
||||||
|
if ( isset( $subscription_items[ $cart_item_session_data[ $this->cart_item_key ]['line_item_id'] ] ) ) {
|
||||||
|
$item_to_renew = $subscription_items[ $cart_item_session_data[ $this->cart_item_key ]['line_item_id'] ];
|
||||||
|
} else {
|
||||||
|
foreach ( $subscription_items as $item ) {
|
||||||
|
if ( $item->get_meta( '_cart_item_key_' . $this->cart_item_key, true ) === $key ) {
|
||||||
|
$item_to_renew = $item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$price = $item_to_renew['line_subtotal'];
|
$price = $item_to_renew['line_subtotal'];
|
||||||
|
|
||||||
@@ -635,33 +649,6 @@ class WCS_Cart_Renewal {
|
|||||||
return $actions;
|
return $actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* When a failed renewal order is being paid for via checkout, make sure WC_Checkout::create_order() preserves its
|
|
||||||
* status as 'failed' until it is paid. By default, it will always set it to 'pending', but we need it left as 'failed'
|
|
||||||
* so that we can correctly identify the status change in @see self::maybe_change_subscription_status().
|
|
||||||
*
|
|
||||||
* @param string Default order status for orders paid for via checkout. Default 'pending'
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
|
||||||
*/
|
|
||||||
public function maybe_preserve_order_status( $order_status ) {
|
|
||||||
|
|
||||||
if ( null !== WC()->session && 'failed' !== $order_status ) {
|
|
||||||
|
|
||||||
$order_id = absint( WC()->session->order_awaiting_payment );
|
|
||||||
|
|
||||||
// Guard against infinite loops in WC 3.0+ where default order staus is set in WC_Abstract_Order::__construct()
|
|
||||||
remove_filter( 'woocommerce_default_order_status', array( &$this, __FUNCTION__ ), 10 );
|
|
||||||
|
|
||||||
if ( $order_id > 0 && ( $order = wc_get_order( $order_id ) ) && wcs_order_contains_renewal( $order ) && $order->has_status( 'failed' ) ) {
|
|
||||||
$order_status = 'failed';
|
|
||||||
}
|
|
||||||
|
|
||||||
add_filter( 'woocommerce_default_order_status', array( &$this, __FUNCTION__ ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return $order_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all the linked renewal/resubscribe items from the cart if a renewal/resubscribe item is removed.
|
* Removes all the linked renewal/resubscribe items from the cart if a renewal/resubscribe item is removed.
|
||||||
*
|
*
|
||||||
@@ -946,7 +933,7 @@ class WCS_Cart_Renewal {
|
|||||||
*/
|
*/
|
||||||
public function product_addons_adjust_price( $adjust_price, $cart_item ) {
|
public function product_addons_adjust_price( $adjust_price, $cart_item ) {
|
||||||
|
|
||||||
if ( true === $adjust_price && isset( $cart_item[ $this->cart_item_key ] ) ) {
|
if ( true === $adjust_price && isset( $cart_item[ $this->cart_item_key ] ) && $this->should_honor_subscription_prices( $cart_item ) ) {
|
||||||
$adjust_price = false;
|
$adjust_price = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -979,10 +966,19 @@ class WCS_Cart_Renewal {
|
|||||||
* order items haven't changed by checking for a cart hash on the order, so we need to set
|
* order items haven't changed by checking for a cart hash on the order, so we need to set
|
||||||
* that here. @see WC_Checkout::create_order()
|
* that here. @see WC_Checkout::create_order()
|
||||||
*
|
*
|
||||||
|
* @param WC_Order|int $order The order object or order ID.
|
||||||
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.14
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.14
|
||||||
*/
|
*/
|
||||||
protected function set_cart_hash( $order_id ) {
|
protected function set_cart_hash( $order ) {
|
||||||
$order = wc_get_order( $order_id );
|
|
||||||
|
if ( ! is_a( $order, 'WC_Abstract_Order' ) ) {
|
||||||
|
$order = wc_get_order( $order );
|
||||||
|
|
||||||
|
if ( ! $order ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Use cart hash generator introduced in WooCommerce 3.6
|
// Use cart hash generator introduced in WooCommerce 3.6
|
||||||
if ( is_callable( array( WC()->cart, 'get_cart_hash' ) ) ) {
|
if ( is_callable( array( WC()->cart, 'get_cart_hash' ) ) ) {
|
||||||
@@ -991,7 +987,8 @@ class WCS_Cart_Renewal {
|
|||||||
$cart_hash = md5( json_encode( wc_clean( WC()->cart->get_cart_for_session() ) ) . WC()->cart->total );
|
$cart_hash = md5( json_encode( wc_clean( WC()->cart->get_cart_for_session() ) ) . WC()->cart->total );
|
||||||
}
|
}
|
||||||
|
|
||||||
wcs_set_objects_property( $order, 'cart_hash', $cart_hash );
|
$order->set_cart_hash( $cart_hash );
|
||||||
|
$order->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1494,7 +1491,7 @@ class WCS_Cart_Renewal {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deteremines if the cart should honor the granfathered subscription/order line item total.
|
* Determines if the cart should honor the grandfathered subscription/order line item total.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.10
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.10
|
||||||
*
|
*
|
||||||
@@ -1590,6 +1587,53 @@ class WCS_Cart_Renewal {
|
|||||||
return current_user_can( 'pay_for_order', $order->get_id() );
|
return current_user_can( 'pay_for_order', $order->get_id() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the order cart hash when paying for a renewal order via the Block Checkout.
|
||||||
|
*
|
||||||
|
* This function is hooked onto the 'woocommerce_order_has_status' filter, is only applied during REST API requests, only applies to the
|
||||||
|
* 'checkout-draft' status (which only Block Checkout orders use) and to renewal orders that are currently being paid for in the cart.
|
||||||
|
* All other order statuses, orders and scenarios remain unaffected by this function.
|
||||||
|
*
|
||||||
|
* This function is necessary to override the default logic in @see DraftOrderTrait::is_valid_draft_order().
|
||||||
|
* This function behaves similarly to @see WCS_Cart_Renewal::update_cart_hash() for the standard checkout and is hooked onto the 'woocommerce_create_order' filter.
|
||||||
|
*
|
||||||
|
* @param bool $has_status Whether the order has the status.
|
||||||
|
* @param WC_Order $order The order.
|
||||||
|
* @param string $status The status to check.
|
||||||
|
*
|
||||||
|
* @return bool Whether the order has the status. Unchanged by this function.
|
||||||
|
*/
|
||||||
|
public function set_renewal_order_cart_hash_on_block_checkout( $has_status, $order, $status ) {
|
||||||
|
/**
|
||||||
|
* We only need to update the order's cart hash when the has_status() check is for 'checkout-draft' (indicating
|
||||||
|
* this is the status check in DraftOrderTrait::is_valid_draft_order()) and the order doesn't have that status. Orders
|
||||||
|
* which already have the checkout-draft status don't need to be updated to bypass the checkout block logic.
|
||||||
|
*/
|
||||||
|
if ( $has_status || 'checkout-draft' !== $status ) {
|
||||||
|
return $has_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is only concerned with updating the order cart hash during REST API requests - which is the request
|
||||||
|
* context where the Store API Checkout Block validates the order for payment resumption.
|
||||||
|
*/
|
||||||
|
if ( ! WC()->is_rest_api_request() ) {
|
||||||
|
return $has_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the order being validated is the order in the cart, then we need to update the cart hash so it can be resumed.
|
||||||
|
if ( $order && $order->get_id() === WC()->session->get( 'store_api_draft_order', 0 ) ) {
|
||||||
|
$cart_order = $this->get_order();
|
||||||
|
|
||||||
|
if ( $cart_order && $cart_order->get_id() === $order->get_id() ) {
|
||||||
|
// Note: We need to pass the order object so the order instance WooCommerce uses will have the updated hash.
|
||||||
|
$this->set_cart_hash( $order );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $has_status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Deprecated */
|
/* Deprecated */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1765,4 +1809,35 @@ class WCS_Cart_Renewal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a failed renewal order is being paid for via checkout, make sure WC_Checkout::create_order() preserves its
|
||||||
|
* status as 'failed' until it is paid. By default, it will always set it to 'pending', but we need it left as 'failed'
|
||||||
|
* so that we can correctly identify the status change in @see self::maybe_change_subscription_status().
|
||||||
|
*
|
||||||
|
* @param string Default order status for orders paid for via checkout. Default 'pending'
|
||||||
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
|
*
|
||||||
|
* @deprecated 6.3.0
|
||||||
|
*/
|
||||||
|
public function maybe_preserve_order_status( $order_status ) {
|
||||||
|
wcs_deprecated_function( __METHOD__, '6.3.0' );
|
||||||
|
if ( null !== WC()->session && 'failed' !== $order_status ) {
|
||||||
|
|
||||||
|
$order_id = absint( WC()->session->order_awaiting_payment );
|
||||||
|
|
||||||
|
// Guard against infinite loops in WC 3.0+ where default order staus is set in WC_Abstract_Order::__construct()
|
||||||
|
remove_filter( 'woocommerce_default_order_status', array( &$this, __FUNCTION__ ), 10 );
|
||||||
|
|
||||||
|
$order = $order_id > 0 ? wc_get_order( $order_id ) : null;
|
||||||
|
|
||||||
|
if ( $order && wcs_order_contains_renewal( $order ) && $order->has_status( 'failed' ) ) {
|
||||||
|
$order_status = 'failed';
|
||||||
|
}
|
||||||
|
|
||||||
|
add_filter( 'woocommerce_default_order_status', array( &$this, __FUNCTION__ ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $order_status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -43,6 +43,7 @@ class WCS_Limiter {
|
|||||||
woocommerce_wp_select(
|
woocommerce_wp_select(
|
||||||
array(
|
array(
|
||||||
'id' => '_subscription_limit',
|
'id' => '_subscription_limit',
|
||||||
|
'class' => 'wc-enhanced-select',
|
||||||
'label' => __( 'Limit subscription', 'woocommerce-subscriptions' ),
|
'label' => __( 'Limit subscription', 'woocommerce-subscriptions' ),
|
||||||
// translators: placeholders are opening and closing link tags
|
// translators: placeholders are opening and closing link tags
|
||||||
'description' => sprintf( __( 'Only allow a customer to have one subscription to this product. %1$sLearn more%2$s.', 'woocommerce-subscriptions' ), '<a href="http://docs.woocommerce.com/document/subscriptions/store-manager-guide/#limit-subscription">', '</a>' ),
|
'description' => sprintf( __( 'Only allow a customer to have one subscription to this product. %1$sLearn more%2$s.', 'woocommerce-subscriptions' ), '<a href="http://docs.woocommerce.com/document/subscriptions/store-manager-guide/#limit-subscription">', '</a>' ),
|
||||||
|
@@ -21,7 +21,9 @@ class WCS_My_Account_Payment_Methods {
|
|||||||
}
|
}
|
||||||
|
|
||||||
add_filter( 'woocommerce_payment_methods_list_item', array( __CLASS__, 'flag_subscription_payment_token_deletions' ), 10, 2 );
|
add_filter( 'woocommerce_payment_methods_list_item', array( __CLASS__, 'flag_subscription_payment_token_deletions' ), 10, 2 );
|
||||||
add_action( 'woocommerce_payment_token_deleted', array( __CLASS__, 'maybe_update_subscriptions_payment_meta' ), 10, 2 );
|
|
||||||
|
// This needs to run after the payment plugins had a chance to execute their delete actions.
|
||||||
|
add_action( 'woocommerce_payment_token_deleted', array( __CLASS__, 'maybe_update_subscriptions_payment_meta' ), 11, 2 );
|
||||||
add_action( 'woocommerce_payment_token_set_default', array( __CLASS__, 'display_default_payment_token_change_notice' ), 10, 2 );
|
add_action( 'woocommerce_payment_token_set_default', array( __CLASS__, 'display_default_payment_token_change_notice' ), 10, 2 );
|
||||||
add_action( 'wp', array( __CLASS__, 'update_subscription_tokens' ) );
|
add_action( 'wp', array( __CLASS__, 'update_subscription_tokens' ) );
|
||||||
|
|
||||||
|
@@ -13,8 +13,6 @@ class WCS_Template_Loader {
|
|||||||
* @var array[] Array of file names and their directory found in templates/
|
* @var array[] Array of file names and their directory found in templates/
|
||||||
*/
|
*/
|
||||||
private static $relocated_templates = [
|
private static $relocated_templates = [
|
||||||
'html-variation-price.php' => 'admin/deprecated/',
|
|
||||||
'html-variation-synchronisation.php' => 'admin/deprecated/',
|
|
||||||
'order-shipping-html.php' => 'admin/deprecated/',
|
'order-shipping-html.php' => 'admin/deprecated/',
|
||||||
'order-tax-html.php' => 'admin/deprecated/',
|
'order-tax-html.php' => 'admin/deprecated/',
|
||||||
'html-admin-notice.php' => 'admin/',
|
'html-admin-notice.php' => 'admin/',
|
||||||
|
@@ -609,6 +609,11 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
];
|
];
|
||||||
|
|
||||||
if ( empty( $existing_meta_data ) ) {
|
if ( empty( $existing_meta_data ) ) {
|
||||||
|
// If we're saving a start date for the first time and it's empty, set it to the created date as a default.
|
||||||
|
if ( '_schedule_start' === $new_meta_data['key'] && empty( $new_meta_data['value'] ) ) {
|
||||||
|
$new_meta_data['value'] = $subscription->get_date( 'date_created' );
|
||||||
|
}
|
||||||
|
|
||||||
$this->data_store_meta->add_meta( $subscription, (object) $new_meta_data );
|
$this->data_store_meta->add_meta( $subscription, (object) $new_meta_data );
|
||||||
} elseif ( $existing_meta_data->meta_value !== $new_meta_data['value'] ) {
|
} elseif ( $existing_meta_data->meta_value !== $new_meta_data['value'] ) {
|
||||||
$new_meta_data['id'] = $existing_meta_data->meta_id;
|
$new_meta_data['id'] = $existing_meta_data->meta_id;
|
||||||
@@ -649,7 +654,7 @@ class WCS_Orders_Table_Subscription_Data_Store extends \Automattic\WooCommerce\I
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're setting the start date and it's missing, we set it to the created date.
|
// If we're reading in the start date and it's missing, set it in memory to the created date.
|
||||||
if ( 'schedule_start' === $prop_key && empty( $meta_data[ $meta_key ] ) ) {
|
if ( 'schedule_start' === $prop_key && empty( $meta_data[ $meta_key ] ) ) {
|
||||||
$meta_data[ $meta_key ] = $subscription->get_date( 'date_created' );
|
$meta_data[ $meta_key ] = $subscription->get_date( 'date_created' );
|
||||||
}
|
}
|
||||||
|
@@ -221,6 +221,10 @@ class WCS_Subscription_Data_Store_CPT extends WC_Order_Data_Store_CPT implements
|
|||||||
foreach ( $this->get_props_to_update( $subscription, $this->subscription_meta_keys_to_props ) as $meta_key => $prop ) {
|
foreach ( $this->get_props_to_update( $subscription, $this->subscription_meta_keys_to_props ) as $meta_key => $prop ) {
|
||||||
$meta_value = ( 'schedule_' == substr( $prop, 0, 9 ) ) ? $subscription->get_date( $prop ) : $subscription->{"get_$prop"}( 'edit' );
|
$meta_value = ( 'schedule_' == substr( $prop, 0, 9 ) ) ? $subscription->get_date( $prop ) : $subscription->{"get_$prop"}( 'edit' );
|
||||||
|
|
||||||
|
if ( 'schedule_start' === $prop && ! $meta_value ) {
|
||||||
|
$meta_value = $subscription->get_date( 'date_created' );
|
||||||
|
}
|
||||||
|
|
||||||
// Store as a string of the boolean for backward compatibility (yep, it's gross)
|
// Store as a string of the boolean for backward compatibility (yep, it's gross)
|
||||||
if ( 'requires_manual_renewal' === $prop ) {
|
if ( 'requires_manual_renewal' === $prop ) {
|
||||||
$meta_value = $meta_value ? 'true' : 'false';
|
$meta_value = $meta_value ? 'true' : 'false';
|
||||||
|
@@ -174,7 +174,7 @@ class WCS_Email_Cancelled_Subscription extends WC_Email {
|
|||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
'description' => __( 'Choose which format of email to send.', 'woocommerce-subscriptions' ),
|
'description' => __( 'Choose which format of email to send.', 'woocommerce-subscriptions' ),
|
||||||
'default' => 'html',
|
'default' => 'html',
|
||||||
'class' => 'email_type',
|
'class' => 'email_type wc-enhanced-select',
|
||||||
'options' => array(
|
'options' => array(
|
||||||
'plain' => _x( 'Plain text', 'email type', 'woocommerce-subscriptions' ),
|
'plain' => _x( 'Plain text', 'email type', 'woocommerce-subscriptions' ),
|
||||||
'html' => _x( 'HTML', 'email type', 'woocommerce-subscriptions' ),
|
'html' => _x( 'HTML', 'email type', 'woocommerce-subscriptions' ),
|
||||||
|
@@ -34,11 +34,6 @@ class WCS_Email_Completed_Renewal_Order extends WC_Email_Customer_Completed_Orde
|
|||||||
$this->template_plain = 'emails/plain/customer-completed-renewal-order.php';
|
$this->template_plain = 'emails/plain/customer-completed-renewal-order.php';
|
||||||
$this->template_base = WC_Subscriptions_Core_Plugin::instance()->get_subscriptions_core_directory( 'templates/' );
|
$this->template_base = WC_Subscriptions_Core_Plugin::instance()->get_subscriptions_core_directory( 'templates/' );
|
||||||
|
|
||||||
// Other settings
|
|
||||||
$this->heading_downloadable = $this->get_option( 'heading_downloadable', _x( 'Your subscription renewal order is complete - download your files', 'Default email heading for email with downloadable files in it', 'woocommerce-subscriptions' ) );
|
|
||||||
// translators: $1: {blogname}, $2: {order_date}, variables will be substituted when email is sent out
|
|
||||||
$this->subject_downloadable = $this->get_option( 'subject_downloadable', sprintf( _x( 'Your %1$s subscription renewal order from %2$s is complete - download your files', 'Default email subject for email with downloadable files in it', 'woocommerce-subscriptions' ), '{blogname}', '{order_date}' ) );
|
|
||||||
|
|
||||||
// Triggers for this email
|
// Triggers for this email
|
||||||
add_action( 'woocommerce_order_status_completed_renewal_notification', array( $this, 'trigger' ) );
|
add_action( 'woocommerce_order_status_completed_renewal_notification', array( $this, 'trigger' ) );
|
||||||
|
|
||||||
@@ -168,4 +163,26 @@ class WCS_Email_Completed_Renewal_Order extends WC_Email_Customer_Completed_Orde
|
|||||||
$this->template_base
|
$this->template_base
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the deprecated public variables for backwards compatibility.
|
||||||
|
*
|
||||||
|
* @param string $key Key.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function __get( $key ) {
|
||||||
|
if ( 'heading_downloadable' === $key ) {
|
||||||
|
wcs_deprecated_argument( __CLASS__ . '::$' . $key, '5.6.0', 'The heading_downloadable property used for emails with downloadable files was removed in WooCommerce 3.1. Use the heading property instead.' );
|
||||||
|
return $this->get_option( 'heading_downloadable', _x( 'Your subscription renewal order is complete - download your files', 'Default email heading for email with downloadable files in it', 'woocommerce-subscriptions' ) );
|
||||||
|
|
||||||
|
} elseif ( 'subject_downloadable' === $key ) {
|
||||||
|
wcs_deprecated_argument( __CLASS__ . '::$' . $key, '5.6.0', 'The subject_downloadabl property used for emails with downloadable files was removed in WooCommerce 3.1. Use the subject property instead.' );
|
||||||
|
// translators: $1: {blogname}, $2: {order_date}, variables will be substituted when email is sent out
|
||||||
|
return $this->get_option( 'subject_downloadable', sprintf( _x( 'Your %1$s subscription renewal order from %2$s is complete - download your files', 'Default email subject for email with downloadable files in it', 'woocommerce-subscriptions' ), '{blogname}', '{order_date}' ) );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,11 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
*/
|
*/
|
||||||
class WCS_Email_Completed_Switch_Order extends WC_Email_Customer_Completed_Order {
|
class WCS_Email_Completed_Switch_Order extends WC_Email_Customer_Completed_Order {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Subscriptions linked to the switch order.
|
||||||
|
*/
|
||||||
|
public $subscriptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
@@ -34,10 +39,6 @@ class WCS_Email_Completed_Switch_Order extends WC_Email_Customer_Completed_Order
|
|||||||
$this->template_plain = 'emails/plain/customer-completed-switch-order.php';
|
$this->template_plain = 'emails/plain/customer-completed-switch-order.php';
|
||||||
$this->template_base = WC_Subscriptions_Core_Plugin::instance()->get_subscriptions_core_directory( 'templates/' );
|
$this->template_base = WC_Subscriptions_Core_Plugin::instance()->get_subscriptions_core_directory( 'templates/' );
|
||||||
|
|
||||||
// Other settings
|
|
||||||
$this->heading_downloadable = $this->get_option( 'heading_downloadable', __( 'Your subscription change is complete - download your files', 'woocommerce-subscriptions' ) );
|
|
||||||
$this->subject_downloadable = $this->get_option( 'subject_downloadable', __( 'Your {blogname} subscription change from {order_date} is complete - download your files', 'woocommerce-subscriptions' ) );
|
|
||||||
|
|
||||||
// Triggers for this email
|
// Triggers for this email
|
||||||
add_action( 'woocommerce_subscriptions_switch_completed_switch_notification', array( $this, 'trigger' ) );
|
add_action( 'woocommerce_subscriptions_switch_completed_switch_notification', array( $this, 'trigger' ) );
|
||||||
|
|
||||||
@@ -171,4 +172,25 @@ class WCS_Email_Completed_Switch_Order extends WC_Email_Customer_Completed_Order
|
|||||||
$this->template_base
|
$this->template_base
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the deprecated public variables for backwards compatibility.
|
||||||
|
*
|
||||||
|
* @param string $key Key.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function __get( $key ) {
|
||||||
|
if ( 'heading_downloadable' === $key ) {
|
||||||
|
wcs_deprecated_argument( __CLASS__ . '::$' . $key, '5.6.0', 'The heading_downloadable property used for emails with downloadable files was removed in WooCommerce 3.1. Use the heading property instead.' );
|
||||||
|
return $this->get_option( 'heading_downloadable', __( 'Your subscription change is complete - download your files', 'woocommerce-subscriptions' ) );
|
||||||
|
|
||||||
|
} elseif ( 'subject_downloadable' === $key ) {
|
||||||
|
wcs_deprecated_argument( __CLASS__ . '::$' . $key, '5.6.0', 'The subject_downloadable property used for emails with downloadable files was removed in WooCommerce 3.1. Use the subject property instead.' );
|
||||||
|
return $this->get_option( 'subject_downloadable', __( 'Your {blogname} subscription change from {order_date} is complete - download your files', 'woocommerce-subscriptions' ) );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -172,7 +172,7 @@ class WCS_Email_Expired_Subscription extends WC_Email {
|
|||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
'description' => __( 'Choose which format of email to send.', 'woocommerce-subscriptions' ),
|
'description' => __( 'Choose which format of email to send.', 'woocommerce-subscriptions' ),
|
||||||
'default' => 'html',
|
'default' => 'html',
|
||||||
'class' => 'email_type',
|
'class' => 'email_type wc-enhanced-select',
|
||||||
'options' => array(
|
'options' => array(
|
||||||
'plain' => _x( 'Plain text', 'email type', 'woocommerce-subscriptions' ),
|
'plain' => _x( 'Plain text', 'email type', 'woocommerce-subscriptions' ),
|
||||||
'html' => _x( 'HTML', 'email type', 'woocommerce-subscriptions' ),
|
'html' => _x( 'HTML', 'email type', 'woocommerce-subscriptions' ),
|
||||||
|
@@ -13,6 +13,11 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
*/
|
*/
|
||||||
class WCS_Email_New_Switch_Order extends WC_Email_New_Order {
|
class WCS_Email_New_Switch_Order extends WC_Email_New_Order {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Subscriptions linked to the switch order.
|
||||||
|
*/
|
||||||
|
public $subscriptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
|
@@ -172,7 +172,7 @@ class WCS_Email_On_Hold_Subscription extends WC_Email {
|
|||||||
'type' => 'select',
|
'type' => 'select',
|
||||||
'description' => __( 'Choose which format of email to send.', 'woocommerce-subscriptions' ),
|
'description' => __( 'Choose which format of email to send.', 'woocommerce-subscriptions' ),
|
||||||
'default' => 'html',
|
'default' => 'html',
|
||||||
'class' => 'email_type',
|
'class' => 'email_type wc-enhanced-select',
|
||||||
'options' => array(
|
'options' => array(
|
||||||
'plain' => _x( 'Plain text', 'email type', 'woocommerce-subscriptions' ),
|
'plain' => _x( 'Plain text', 'email type', 'woocommerce-subscriptions' ),
|
||||||
'html' => _x( 'HTML', 'email type', 'woocommerce-subscriptions' ),
|
'html' => _x( 'HTML', 'email type', 'woocommerce-subscriptions' ),
|
||||||
|
@@ -44,6 +44,7 @@ class WCS_Array_Property_Post_Meta_Black_Magic implements ArrayAccess {
|
|||||||
* @param string $key
|
* @param string $key
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetGet( $key ) {
|
public function offsetGet( $key ) {
|
||||||
return get_post_meta( $this->product_id, $this->maybe_prefix_meta_key( $key ) );
|
return get_post_meta( $this->product_id, $this->maybe_prefix_meta_key( $key ) );
|
||||||
}
|
}
|
||||||
@@ -53,6 +54,7 @@ class WCS_Array_Property_Post_Meta_Black_Magic implements ArrayAccess {
|
|||||||
* @param string $key
|
* @param string $key
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
*/
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetSet( $key, $value ) {
|
public function offsetSet( $key, $value ) {
|
||||||
update_post_meta( $this->product_id, $this->maybe_prefix_meta_key( $key ), $value );
|
update_post_meta( $this->product_id, $this->maybe_prefix_meta_key( $key ), $value );
|
||||||
}
|
}
|
||||||
@@ -62,6 +64,7 @@ class WCS_Array_Property_Post_Meta_Black_Magic implements ArrayAccess {
|
|||||||
* @param string $key
|
* @param string $key
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetExists( $key ) {
|
public function offsetExists( $key ) {
|
||||||
return metadata_exists( 'post', $this->product_id, $this->maybe_prefix_meta_key( $key ) );
|
return metadata_exists( 'post', $this->product_id, $this->maybe_prefix_meta_key( $key ) );
|
||||||
}
|
}
|
||||||
@@ -69,6 +72,7 @@ class WCS_Array_Property_Post_Meta_Black_Magic implements ArrayAccess {
|
|||||||
/**
|
/**
|
||||||
* Nothing to do here as we access post meta directly.
|
* Nothing to do here as we access post meta directly.
|
||||||
*/
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
public function offsetUnset( $key ) {
|
public function offsetUnset( $key ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -215,6 +215,9 @@ function wcs_create_order_from_subscription( $subscription, $type ) {
|
|||||||
// If we got here, the subscription was created without problems
|
// If we got here, the subscription was created without problems
|
||||||
$transaction->commit();
|
$transaction->commit();
|
||||||
|
|
||||||
|
// Delete the transient that caches whether the order needs processing. Because we've added line items, the order may now need processing.
|
||||||
|
delete_transient( 'wc_order_' . $new_order->get_id() . '_needs_processing' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters the new order created from the subscription.
|
* Filters the new order created from the subscription.
|
||||||
*
|
*
|
||||||
|
@@ -41,7 +41,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
// Subscription Period Interval
|
// Subscription Period Interval
|
||||||
woocommerce_wp_select( array(
|
woocommerce_wp_select( array(
|
||||||
'id' => 'variable_subscription_period_interval[' . $loop . ']',
|
'id' => 'variable_subscription_period_interval[' . $loop . ']',
|
||||||
'class' => 'wc_input_subscription_period_interval',
|
'class' => 'wc_input_subscription_period_interval wc-enhanced-select',
|
||||||
'wrapper_class' => '_subscription_period_interval_field',
|
'wrapper_class' => '_subscription_period_interval_field',
|
||||||
'label' => __( 'Subscription Periods', 'woocommerce-subscriptions' ),
|
'label' => __( 'Subscription Periods', 'woocommerce-subscriptions' ),
|
||||||
'options' => wcs_get_subscription_period_interval_strings(),
|
'options' => wcs_get_subscription_period_interval_strings(),
|
||||||
@@ -52,7 +52,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
// Billing Period
|
// Billing Period
|
||||||
woocommerce_wp_select( array(
|
woocommerce_wp_select( array(
|
||||||
'id' => 'variable_subscription_period[' . $loop . ']',
|
'id' => 'variable_subscription_period[' . $loop . ']',
|
||||||
'class' => 'wc_input_subscription_period',
|
'class' => 'wc_input_subscription_period wc-enhanced-select',
|
||||||
'wrapper_class' => '_subscription_period_field',
|
'wrapper_class' => '_subscription_period_field',
|
||||||
'label' => __( 'Billing Period', 'woocommerce-subscriptions' ),
|
'label' => __( 'Billing Period', 'woocommerce-subscriptions' ),
|
||||||
'value' => $subscription_period,
|
'value' => $subscription_period,
|
||||||
@@ -64,7 +64,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
// Subscription Length
|
// Subscription Length
|
||||||
woocommerce_wp_select( array(
|
woocommerce_wp_select( array(
|
||||||
'id' => 'variable_subscription_length[' . $loop . ']',
|
'id' => 'variable_subscription_length[' . $loop . ']',
|
||||||
'class' => 'wc_input_subscription_length',
|
'class' => 'wc_input_subscription_length wc-enhanced-select',
|
||||||
'wrapper_class' => '_subscription_length_field',
|
'wrapper_class' => '_subscription_length_field',
|
||||||
'label' => __( 'Subscription Length', 'woocommerce-subscriptions' ),
|
'label' => __( 'Subscription Length', 'woocommerce-subscriptions' ),
|
||||||
'options' => wcs_get_subscription_ranges( $subscription_period ),
|
'options' => wcs_get_subscription_ranges( $subscription_period ),
|
||||||
@@ -110,7 +110,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
// Trial Period
|
// Trial Period
|
||||||
woocommerce_wp_select( array(
|
woocommerce_wp_select( array(
|
||||||
'id' => 'variable_subscription_trial_period[' . $loop . ']',
|
'id' => 'variable_subscription_trial_period[' . $loop . ']',
|
||||||
'class' => 'wc_input_subscription_trial_period',
|
'class' => 'wc_input_subscription_trial_period wc-enhanced-select',
|
||||||
'wrapper_class' => '_subscription_trial_period_field',
|
'wrapper_class' => '_subscription_trial_period_field',
|
||||||
'label' => __( 'Subscription Trial Period', 'woocommerce-subscriptions' ),
|
'label' => __( 'Subscription Trial Period', 'woocommerce-subscriptions' ),
|
||||||
'options' => wcs_get_available_time_periods(),
|
'options' => wcs_get_available_time_periods(),
|
||||||
|
@@ -17,7 +17,7 @@ global $wp_locale;
|
|||||||
<td colspan="1" class="subscription_sync_week_month"<?php echo esc_attr( $display_week_month_select ); ?>>
|
<td colspan="1" class="subscription_sync_week_month"<?php echo esc_attr( $display_week_month_select ); ?>>
|
||||||
<?php woocommerce_wp_select( array(
|
<?php woocommerce_wp_select( array(
|
||||||
'id' => 'variable' . WC_Subscriptions_Synchroniser::$post_meta_key . '[' . $loop . ']',
|
'id' => 'variable' . WC_Subscriptions_Synchroniser::$post_meta_key . '[' . $loop . ']',
|
||||||
'class' => 'wc_input_subscription_payment_sync',
|
'class' => 'wc_input_subscription_payment_sync wc-enhanced-select',
|
||||||
'wrapper_class' => '_subscription_payment_sync_field',
|
'wrapper_class' => '_subscription_payment_sync_field',
|
||||||
'label' => WC_Subscriptions_Synchroniser::$sync_field_label,
|
'label' => WC_Subscriptions_Synchroniser::$sync_field_label,
|
||||||
'options' => WC_Subscriptions_Synchroniser::get_billing_period_ranges( $subscription_period ),
|
'options' => WC_Subscriptions_Synchroniser::get_billing_period_ranges( $subscription_period ),
|
||||||
@@ -30,7 +30,7 @@ global $wp_locale;
|
|||||||
<label><?php esc_html_e( 'Synchronise Renewals', 'woocommerce-subscriptions' ); ?></label>
|
<label><?php esc_html_e( 'Synchronise Renewals', 'woocommerce-subscriptions' ); ?></label>
|
||||||
<?php woocommerce_wp_text_input( array(
|
<?php woocommerce_wp_text_input( array(
|
||||||
'id' => 'variable' . WC_Subscriptions_Synchroniser::$post_meta_key_day . '[' . $loop . ']',
|
'id' => 'variable' . WC_Subscriptions_Synchroniser::$post_meta_key_day . '[' . $loop . ']',
|
||||||
'class' => 'wc_input_subscription_payment_sync',
|
'class' => 'wc_input_subscription_payment_sync wc-enhanced-select',
|
||||||
'wrapper_class' => '_subscription_payment_sync_field',
|
'wrapper_class' => '_subscription_payment_sync_field',
|
||||||
'label' => WC_Subscriptions_Synchroniser::$sync_field_label,
|
'label' => WC_Subscriptions_Synchroniser::$sync_field_label,
|
||||||
'placeholder' => _x( 'Day', 'input field placeholder for day field for annual subscriptions', 'woocommerce-subscriptions' ),
|
'placeholder' => _x( 'Day', 'input field placeholder for day field for annual subscriptions', 'woocommerce-subscriptions' ),
|
||||||
@@ -45,7 +45,7 @@ global $wp_locale;
|
|||||||
|
|
||||||
woocommerce_wp_select( array(
|
woocommerce_wp_select( array(
|
||||||
'id' => 'variable' . WC_Subscriptions_Synchroniser::$post_meta_key_month . '[' . $loop . ']',
|
'id' => 'variable' . WC_Subscriptions_Synchroniser::$post_meta_key_month . '[' . $loop . ']',
|
||||||
'class' => 'wc_input_subscription_payment_sync',
|
'class' => 'wc_input_subscription_payment_sync wc-enhanced-select',
|
||||||
'wrapper_class' => '_subscription_payment_sync_field',
|
'wrapper_class' => '_subscription_payment_sync_field',
|
||||||
'label' => '',
|
'label' => '',
|
||||||
'options' => $wp_locale->month,
|
'options' => $wp_locale->month,
|
||||||
|
@@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<div class="variable_subscription_trial variable_subscription_pricing_2_3 show_if_variable-subscription variable_subscription_trial_sign_up">
|
<div class="variable_subscription_trial variable_subscription_pricing_2_3 show_if_variable-subscription variable_subscription_trial_sign_up" style="display: none">
|
||||||
<p class="form-row form-row-first form-field show_if_variable-subscription sign-up-fee-cell">
|
<p class="form-row form-row-first form-field show_if_variable-subscription sign-up-fee-cell">
|
||||||
<label for="variable_subscription_sign_up_fee[<?php echo esc_attr( $loop ); ?>]"><?php printf( esc_html__( 'Sign-up fee (%s)', 'woocommerce-subscriptions' ), esc_html( get_woocommerce_currency_symbol() ) ); ?></label>
|
<label for="variable_subscription_sign_up_fee[<?php echo esc_attr( $loop ); ?>]"><?php printf( esc_html__( 'Sign-up fee (%s)', 'woocommerce-subscriptions' ), esc_html( get_woocommerce_currency_symbol() ) ); ?></label>
|
||||||
<input type="text" class="wc_input_price wc_input_subscription_intial_price wc_input_subscription_initial_price" name="variable_subscription_sign_up_fee[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_price( WC_Subscriptions_Product::get_sign_up_fee( $variation_product ) ) ); ?>" placeholder="<?php echo esc_attr_x( 'e.g. 9.90', 'example price', 'woocommerce-subscriptions' ); ?>">
|
<input type="text" class="wc_input_price wc_input_subscription_intial_price wc_input_subscription_initial_price" name="variable_subscription_sign_up_fee[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_price( WC_Subscriptions_Product::get_sign_up_fee( $variation_product ) ) ); ?>" placeholder="<?php echo esc_attr_x( 'e.g. 9.90', 'example price', 'woocommerce-subscriptions' ); ?>">
|
||||||
@@ -29,14 +29,14 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
<input type="text" class="wc_input_subscription_trial_length" name="variable_subscription_trial_length[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( WC_Subscriptions_Product::get_trial_length( $variation_product ) ); ?>">
|
<input type="text" class="wc_input_subscription_trial_length" name="variable_subscription_trial_length[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( WC_Subscriptions_Product::get_trial_length( $variation_product ) ); ?>">
|
||||||
|
|
||||||
<label for="variable_subscription_trial_period[<?php echo esc_attr( $loop ); ?>]" class="wcs_hidden_label"><?php esc_html_e( 'Subscription trial period:', 'woocommerce-subscriptions' ); ?></label>
|
<label for="variable_subscription_trial_period[<?php echo esc_attr( $loop ); ?>]" class="wcs_hidden_label"><?php esc_html_e( 'Subscription trial period:', 'woocommerce-subscriptions' ); ?></label>
|
||||||
<select name="variable_subscription_trial_period[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_trial_period">
|
<select name="variable_subscription_trial_period[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_trial_period wc-enhanced-select">
|
||||||
<?php foreach ( wcs_get_available_time_periods() as $key => $value ) : ?>
|
<?php foreach ( wcs_get_available_time_periods() as $key => $value ) : ?>
|
||||||
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, WC_Subscriptions_Product::get_trial_period( $variation_product ) ); ?>><?php echo esc_html( $value ); ?></option>
|
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, WC_Subscriptions_Product::get_trial_period( $variation_product ) ); ?>><?php echo esc_html( $value ); ?></option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="variable_subscription_pricing variable_subscription_pricing_2_3 show_if_variable-subscription">
|
<div class="variable_subscription_pricing variable_subscription_pricing_2_3 show_if_variable-subscription" style="display: none">
|
||||||
<p class="form-row form-row-first form-field show_if_variable-subscription _subscription_price_field">
|
<p class="form-row form-row-first form-field show_if_variable-subscription _subscription_price_field">
|
||||||
<label for="variable_subscription_price[<?php echo esc_attr( $loop ); ?>]">
|
<label for="variable_subscription_price[<?php echo esc_attr( $loop ); ?>]">
|
||||||
<?php
|
<?php
|
||||||
@@ -47,26 +47,26 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
<input type="text" class="wc_input_price wc_input_subscription_price" name="variable_subscription_price[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_price( WC_Subscriptions_Product::get_regular_price( $variation_product ) ) ); ?>" placeholder="<?php echo esc_attr_x( 'e.g. 9.90', 'example price', 'woocommerce-subscriptions' ); ?>">
|
<input type="text" class="wc_input_price wc_input_subscription_price" name="variable_subscription_price[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_price( WC_Subscriptions_Product::get_regular_price( $variation_product ) ) ); ?>" placeholder="<?php echo esc_attr_x( 'e.g. 9.90', 'example price', 'woocommerce-subscriptions' ); ?>">
|
||||||
|
|
||||||
<label for="variable_subscription_period_interval[<?php echo esc_attr( $loop ); ?>]" class="wcs_hidden_label"><?php esc_html_e( 'Billing interval:', 'woocommerce-subscriptions' ); ?></label>
|
<label for="variable_subscription_period_interval[<?php echo esc_attr( $loop ); ?>]" class="wcs_hidden_label"><?php esc_html_e( 'Billing interval:', 'woocommerce-subscriptions' ); ?></label>
|
||||||
<select name="variable_subscription_period_interval[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_period_interval">
|
<select name="variable_subscription_period_interval[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_period_interval wc-enhanced-select">
|
||||||
<?php foreach ( wcs_get_subscription_period_interval_strings() as $key => $value ) : ?>
|
<?php foreach ( wcs_get_subscription_period_interval_strings() as $key => $value ) : ?>
|
||||||
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, WC_Subscriptions_Product::get_interval( $variation_product ) ); ?>><?php echo esc_html( $value ); ?></option>
|
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, WC_Subscriptions_Product::get_interval( $variation_product ) ); ?>><?php echo esc_html( $value ); ?></option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="variable_subscription_period[<?php echo esc_attr( $loop ); ?>]" class="wcs_hidden_label"><?php esc_html_e( 'Billing Period:', 'woocommerce-subscriptions' ); ?></label>
|
<label for="variable_subscription_period[<?php echo esc_attr( $loop ); ?>]" class="wcs_hidden_label"><?php esc_html_e( 'Billing Period:', 'woocommerce-subscriptions' ); ?></label>
|
||||||
<select name="variable_subscription_period[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_period">
|
<select name="variable_subscription_period[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_period wc-enhanced-select">
|
||||||
<?php foreach ( wcs_get_subscription_period_strings() as $key => $value ) : ?>
|
<?php foreach ( wcs_get_subscription_period_strings() as $key => $value ) : ?>
|
||||||
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, $billing_period ); ?>><?php echo esc_html( $value ); ?></option>
|
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, $billing_period ); ?>><?php echo esc_html( $value ); ?></option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
<p class="form-row form-row-last show_if_variable-subscription _subscription_length_field">
|
<p class="form-row form-row-last show_if_variable-subscription _subscription_length_field" style="display: none">
|
||||||
<label for="variable_subscription_length[<?php echo esc_attr( $loop ); ?>]">
|
<label for="variable_subscription_length[<?php echo esc_attr( $loop ); ?>]">
|
||||||
<?php esc_html_e( 'Expire after', 'woocommerce-subscriptions' ); ?>
|
<?php esc_html_e( 'Expire after', 'woocommerce-subscriptions' ); ?>
|
||||||
<?php echo wcs_help_tip( _x( 'Automatically expire the subscription after this length of time. This length is in addition to any free trial or amount of time provided before a synchronised first renewal date.', 'Subscription Length dropdown\'s description in pricing fields', 'woocommerce-subscriptions' ) ); ?>
|
<?php echo wcs_help_tip( _x( 'Automatically expire the subscription after this length of time. This length is in addition to any free trial or amount of time provided before a synchronised first renewal date.', 'Subscription Length dropdown\'s description in pricing fields', 'woocommerce-subscriptions' ) ); ?>
|
||||||
</label>
|
</label>
|
||||||
<select name="variable_subscription_length[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_length">
|
<select name="variable_subscription_length[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_length wc-enhanced-select">
|
||||||
<?php foreach ( wcs_get_subscription_ranges( $billing_period ) as $key => $value ) : ?>
|
<?php foreach ( wcs_get_subscription_ranges( $billing_period ) as $key => $value ) : ?>
|
||||||
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, WC_Subscriptions_Product::get_length( $variation_product ) ); ?>> <?php echo esc_html( $value ); ?></option>
|
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, WC_Subscriptions_Product::get_length( $variation_product ) ); ?>> <?php echo esc_html( $value ); ?></option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
@@ -15,14 +15,14 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
global $wp_locale;
|
global $wp_locale;
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<div class="variable_subscription_sync show_if_variable-subscription variable_subscription_pricing_2_3">
|
<div class="variable_subscription_sync show_if_variable-subscription variable_subscription_pricing_2_3" style="display: none">
|
||||||
<div class="form-row form-row-full">
|
<div class="form-row form-row-full">
|
||||||
<div class="subscription_sync_week_month" style="<?php echo esc_attr( $display_week_month_select ); ?>">
|
<div class="subscription_sync_week_month" style="<?php echo esc_attr( $display_week_month_select ); ?>">
|
||||||
<label for="variable_subscription_payment_sync_date[<?php echo esc_attr( $loop ); ?>]">
|
<label for="variable_subscription_payment_sync_date[<?php echo esc_attr( $loop ); ?>]">
|
||||||
<?php echo esc_html( WC_Subscriptions_Synchroniser::$sync_field_label ); ?>
|
<?php echo esc_html( WC_Subscriptions_Synchroniser::$sync_field_label ); ?>
|
||||||
<?php echo wcs_help_tip( WC_Subscriptions_Synchroniser::$sync_description ); ?>
|
<?php echo wcs_help_tip( WC_Subscriptions_Synchroniser::$sync_description ); ?>
|
||||||
</label>
|
</label>
|
||||||
<select name="variable_subscription_payment_sync_date[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_payment_sync">
|
<select name="variable_subscription_payment_sync_date[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_payment_sync wc-enhanced-select">
|
||||||
<?php foreach ( WC_Subscriptions_Synchroniser::get_billing_period_ranges( $subscription_period ) as $key => $value ) : ?>
|
<?php foreach ( WC_Subscriptions_Synchroniser::get_billing_period_ranges( $subscription_period ) as $key => $value ) : ?>
|
||||||
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, $payment_day ); ?>><?php echo esc_html( $value ); ?></option>
|
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, $payment_day ); ?>><?php echo esc_html( $value ); ?></option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
@@ -33,7 +33,7 @@ global $wp_locale;
|
|||||||
<?php echo esc_html( WC_Subscriptions_Synchroniser::$sync_field_label ); ?>
|
<?php echo esc_html( WC_Subscriptions_Synchroniser::$sync_field_label ); ?>
|
||||||
<?php echo wcs_help_tip( WC_Subscriptions_Synchroniser::$sync_description_year ); ?>
|
<?php echo wcs_help_tip( WC_Subscriptions_Synchroniser::$sync_description_year ); ?>
|
||||||
</label>
|
</label>
|
||||||
<select name="variable_subscription_payment_sync_date_month[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_payment_sync wc_input_subscription_payment_sync_month">
|
<select name="variable_subscription_payment_sync_date_month[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_payment_sync wc_input_subscription_payment_sync_month wc-enhanced-select">
|
||||||
<?php foreach ( WC_Subscriptions_Synchroniser::get_year_sync_options() as $key => $value ) : ?>
|
<?php foreach ( WC_Subscriptions_Synchroniser::get_year_sync_options() as $key => $value ) : ?>
|
||||||
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, $payment_month ); ?>><?php echo esc_html( $value ); ?></option>
|
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, $payment_month ); ?>><?php echo esc_html( $value ); ?></option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
@@ -174,7 +174,7 @@ function wcs_create_subscription( $args = array() ) {
|
|||||||
|
|
||||||
$subscription->set_customer_note( $args['customer_note'] ?? '' );
|
$subscription->set_customer_note( $args['customer_note'] ?? '' );
|
||||||
$subscription->set_customer_id( $args['customer_id'] );
|
$subscription->set_customer_id( $args['customer_id'] );
|
||||||
$subscription->set_date_created( $args['date_created'] );
|
$subscription->set_date_created( wcs_date_to_time( $args['date_created'] ) );
|
||||||
$subscription->set_created_via( $args['created_via'] );
|
$subscription->set_created_via( $args['created_via'] );
|
||||||
$subscription->set_currency( $args['currency'] );
|
$subscription->set_currency( $args['currency'] );
|
||||||
$subscription->set_prices_include_tax( 'no' !== $args['prices_include_tax'] );
|
$subscription->set_prices_include_tax( 'no' !== $args['prices_include_tax'] );
|
||||||
|
@@ -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.2.0
|
* Version: 6.4.0
|
||||||
*/
|
*/
|
||||||
|
@@ -5,10 +5,10 @@
|
|||||||
* 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: 5.5.0
|
* Version: 5.6.0
|
||||||
*
|
*
|
||||||
* WC requires at least: 7.6.0
|
* WC requires at least: 7.7.0
|
||||||
* WC tested up to: 8.1.0
|
* WC tested up to: 8.2.0
|
||||||
* Woo: 27147:6115e6d7e297b623a169fdcf5728b224
|
* Woo: 27147:6115e6d7e297b623a169fdcf5728b224
|
||||||
*
|
*
|
||||||
* Copyright 2019 WooCommerce
|
* Copyright 2019 WooCommerce
|
||||||
@@ -77,7 +77,7 @@ class WC_Subscriptions {
|
|||||||
public static $plugin_file = __FILE__;
|
public static $plugin_file = __FILE__;
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
public static $version = '5.5.0'; // WRCS: DEFINED_VERSION.
|
public static $version = '5.6.0'; // WRCS: DEFINED_VERSION.
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
public static $wc_minimum_supported_version = '7.7';
|
public static $wc_minimum_supported_version = '7.7';
|
||||||
@@ -145,7 +145,7 @@ class WC_Subscriptions {
|
|||||||
} else {
|
} else {
|
||||||
// Trigger an error consistant with PHP if the function called doesn't exist.
|
// Trigger an error consistant with PHP if the function called doesn't exist.
|
||||||
$class = __CLASS__;
|
$class = __CLASS__;
|
||||||
$trace = debug_backtrace();
|
$trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 1 );
|
||||||
$file = $trace[0]['file'];
|
$file = $trace[0]['file'];
|
||||||
$line = $trace[0]['line'];
|
$line = $trace[0]['line'];
|
||||||
trigger_error( "Call to undefined method $class::$method() in $file on line $line", E_USER_ERROR ); //phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
|
trigger_error( "Call to undefined method $class::$method() in $file on line $line", E_USER_ERROR ); //phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
|
||||||
|
Reference in New Issue
Block a user