mirror of
https://github.com/pronamic/woocommerce-subscriptions.git
synced 2025-10-08 02:24:02 +00:00
Updates to 7.4.0
This commit is contained in:
@@ -1,5 +1,13 @@
|
|||||||
*** WooCommerce Subscriptions Changelog ***
|
*** WooCommerce Subscriptions Changelog ***
|
||||||
|
|
||||||
|
2025-04-14 - version 7.4.0
|
||||||
|
* Update: Increase the number of args accepted by wcs_get_subscriptions(), to bring about parity with wc_get_orders().
|
||||||
|
* Dev: Update wcs_maybe_prefix_key() and wcs_maybe_unprefix_key() to support an array of keys.
|
||||||
|
* Fix: Prevent sending renewal reminders for orders with a 0 total.
|
||||||
|
* Fix: Ensure the second parameter passed to the 'get_edit_post_link' filter is an integer.
|
||||||
|
* Fix: Prevent WooCommerce Subscriptions buttons from overflowing in the View subscription page
|
||||||
|
* Dev: Update subscriptions-core to 8.2.0
|
||||||
|
|
||||||
2025-03-31 - version 7.3.1
|
2025-03-31 - version 7.3.1
|
||||||
* Update: Display the subscription parent order icon in the WooCommerce Orders list table by default.
|
* Update: Display the subscription parent order icon in the WooCommerce Orders list table by default.
|
||||||
* Dev: Update subscriptions-core to 8.1.1
|
* Dev: Update subscriptions-core to 8.1.1
|
||||||
|
@@ -66,8 +66,8 @@ class WCS_Report_Dashboard {
|
|||||||
WHERE wcorder.post_type IN ( 'shop_order' )
|
WHERE wcorder.post_type IN ( 'shop_order' )
|
||||||
AND wcsubs.post_type IN ( 'shop_subscription' )
|
AND wcsubs.post_type IN ( 'shop_subscription' )
|
||||||
AND wcorder.post_status IN ( 'wc-completed', 'wc-processing', 'wc-on-hold', 'wc-refunded' )
|
AND wcorder.post_status IN ( 'wc-completed', 'wc-processing', 'wc-on-hold', 'wc-refunded' )
|
||||||
AND wcorder.post_date >= '%s'
|
AND wcorder.post_date >= %s
|
||||||
AND wcorder.post_date < '%s'",
|
AND wcorder.post_date < %s",
|
||||||
date( 'Y-m-01', current_time( 'timestamp' ) ),
|
date( 'Y-m-01', current_time( 'timestamp' ) ),
|
||||||
date( 'Y-m-d', strtotime( '+1 DAY', current_time( 'timestamp' ) ) )
|
date( 'Y-m-d', strtotime( '+1 DAY', current_time( 'timestamp' ) ) )
|
||||||
);
|
);
|
||||||
@@ -76,6 +76,7 @@ class WCS_Report_Dashboard {
|
|||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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;
|
||||||
}
|
}
|
||||||
@@ -95,8 +96,8 @@ class WCS_Report_Dashboard {
|
|||||||
WHERE wcorder.post_type IN ( 'shop_order' )
|
WHERE wcorder.post_type IN ( 'shop_order' )
|
||||||
AND wcsubs.post_type IN ( 'shop_subscription' )
|
AND wcsubs.post_type IN ( 'shop_subscription' )
|
||||||
AND wcorder.post_status IN ( 'wc-completed', 'wc-processing', 'wc-on-hold', 'wc-refunded' )
|
AND wcorder.post_status IN ( 'wc-completed', 'wc-processing', 'wc-on-hold', 'wc-refunded' )
|
||||||
AND wcorder.post_date >= '%s'
|
AND wcorder.post_date >= %s
|
||||||
AND wcorder.post_date < '%s'
|
AND wcorder.post_date < %s
|
||||||
) AS orders ON orders.ID = order_total_meta.post_id
|
) AS orders ON orders.ID = order_total_meta.post_id
|
||||||
WHERE order_total_meta.meta_key = '_order_total'",
|
WHERE order_total_meta.meta_key = '_order_total'",
|
||||||
date( 'Y-m-01', current_time( 'timestamp' ) ),
|
date( 'Y-m-01', current_time( 'timestamp' ) ),
|
||||||
@@ -107,6 +108,7 @@ class WCS_Report_Dashboard {
|
|||||||
|
|
||||||
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
if ( $args['no_cache'] || false === $cached_results || ! isset( $cached_results[ $query_hash ] ) ) {
|
||||||
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
$wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$cached_results[ $query_hash ] = $wpdb->get_var( apply_filters( 'woocommerce_subscription_dashboard_status_widget_signup_revenue_query', $query ) );
|
$cached_results[ $query_hash ] = $wpdb->get_var( apply_filters( 'woocommerce_subscription_dashboard_status_widget_signup_revenue_query', $query ) );
|
||||||
$update_cache = true;
|
$update_cache = true;
|
||||||
}
|
}
|
||||||
@@ -125,8 +127,8 @@ class WCS_Report_Dashboard {
|
|||||||
)
|
)
|
||||||
WHERE wcorder.post_type IN ( 'shop_order' )
|
WHERE wcorder.post_type IN ( 'shop_order' )
|
||||||
AND wcorder.post_status IN ( 'wc-completed', 'wc-processing', 'wc-on-hold', 'wc-refunded' )
|
AND wcorder.post_status IN ( 'wc-completed', 'wc-processing', 'wc-on-hold', 'wc-refunded' )
|
||||||
AND wcorder.post_date >= '%s'
|
AND wcorder.post_date >= %s
|
||||||
AND wcorder.post_date < '%s'",
|
AND wcorder.post_date < %s",
|
||||||
date( 'Y-m-01', current_time( 'timestamp' ) ),
|
date( 'Y-m-01', current_time( 'timestamp' ) ),
|
||||||
date( 'Y-m-d', strtotime( '+1 DAY', current_time( 'timestamp' ) ) )
|
date( 'Y-m-d', strtotime( '+1 DAY', current_time( 'timestamp' ) ) )
|
||||||
);
|
);
|
||||||
@@ -135,6 +137,7 @@ class WCS_Report_Dashboard {
|
|||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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;
|
||||||
}
|
}
|
||||||
@@ -157,8 +160,8 @@ class WCS_Report_Dashboard {
|
|||||||
)
|
)
|
||||||
WHERE wcorder.post_type IN ( 'shop_order' )
|
WHERE wcorder.post_type IN ( 'shop_order' )
|
||||||
AND wcorder.post_status IN ( 'wc-completed', 'wc-processing', 'wc-on-hold', 'wc-refunded' )
|
AND wcorder.post_status IN ( 'wc-completed', 'wc-processing', 'wc-on-hold', 'wc-refunded' )
|
||||||
AND wcorder.post_date >= '%s'
|
AND wcorder.post_date >= %s
|
||||||
AND wcorder.post_date < '%s'
|
AND wcorder.post_date < %s
|
||||||
) AS orders ON orders.ID = order_total_meta.post_id
|
) AS orders ON orders.ID = order_total_meta.post_id
|
||||||
WHERE order_total_meta.meta_key = '_order_total'",
|
WHERE order_total_meta.meta_key = '_order_total'",
|
||||||
date( 'Y-m-01', current_time( 'timestamp' ) ),
|
date( 'Y-m-01', current_time( 'timestamp' ) ),
|
||||||
@@ -169,6 +172,7 @@ class WCS_Report_Dashboard {
|
|||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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;
|
||||||
}
|
}
|
||||||
@@ -183,7 +187,8 @@ class WCS_Report_Dashboard {
|
|||||||
ON wcsubs.ID = wcsmeta_cancel.post_id
|
ON wcsubs.ID = wcsmeta_cancel.post_id
|
||||||
AND wcsmeta_cancel.meta_key = '_schedule_cancelled'
|
AND wcsmeta_cancel.meta_key = '_schedule_cancelled'
|
||||||
AND wcsubs.post_status NOT IN ( 'trash', 'auto-draft' )
|
AND wcsubs.post_status NOT IN ( 'trash', 'auto-draft' )
|
||||||
AND CONVERT_TZ( wcsmeta_cancel.meta_value, '+00:00', '{$site_timezone}' ) BETWEEN '%s' AND '%s'",
|
AND CONVERT_TZ( wcsmeta_cancel.meta_value, '+00:00', %s ) BETWEEN %s AND %s",
|
||||||
|
$site_timezone,
|
||||||
date( 'Y-m-01', current_time( 'timestamp' ) ),
|
date( 'Y-m-01', current_time( 'timestamp' ) ),
|
||||||
date( 'Y-m-d', strtotime( '+1 DAY', current_time( 'timestamp' ) ) )
|
date( 'Y-m-d', strtotime( '+1 DAY', current_time( 'timestamp' ) ) )
|
||||||
);
|
);
|
||||||
@@ -192,6 +197,7 @@ class WCS_Report_Dashboard {
|
|||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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;
|
||||||
}
|
}
|
||||||
|
@@ -74,29 +74,31 @@ class WCS_Report_Retention_Rate extends WC_Admin_Report {
|
|||||||
$oldest_subscription_age = floor( $oldest_subscription_age_in_days / $days_in_interval_period );
|
$oldest_subscription_age = floor( $oldest_subscription_age_in_days / $days_in_interval_period );
|
||||||
|
|
||||||
// Now get all subscriptions, not just those that have ended, and find out how long they have lived (or if they haven't ended yet, consider them as being alive for one period longer than the longest living subsription)
|
// Now get all subscriptions, not just those that have ended, and find out how long they have lived (or if they haven't ended yet, consider them as being alive for one period longer than the longest living subsription)
|
||||||
$base_query = $wpdb->prepare(
|
$subscription_ages = $wpdb->get_results(
|
||||||
"SELECT
|
$wpdb->prepare(
|
||||||
IF(COALESCE(cancelled_date.meta_value,end_date.meta_value) <> '0',CEIL(DATEDIFF(CAST(COALESCE(cancelled_date.meta_value,end_date.meta_value) AS DATETIME),posts.post_date_gmt)/%d),%d) as periods_active,
|
"SELECT
|
||||||
COUNT(posts.ID) as count
|
IF(COALESCE(cancelled_date.meta_value,end_date.meta_value) <> '0',CEIL(DATEDIFF(CAST(COALESCE(cancelled_date.meta_value,end_date.meta_value) AS DATETIME),posts.post_date_gmt)/%d),%d) as periods_active,
|
||||||
FROM {$wpdb->prefix}posts posts
|
COUNT(posts.ID) as count
|
||||||
LEFT JOIN {$wpdb->prefix}postmeta cancelled_date
|
FROM {$wpdb->prefix}posts posts
|
||||||
ON posts.ID = cancelled_date.post_id
|
LEFT JOIN {$wpdb->prefix}postmeta cancelled_date
|
||||||
AND cancelled_date.meta_key = %s
|
ON posts.ID = cancelled_date.post_id
|
||||||
AND cancelled_date.meta_value <> '0'
|
AND cancelled_date.meta_key = %s
|
||||||
LEFT JOIN {$wpdb->prefix}postmeta end_date
|
AND cancelled_date.meta_value <> '0'
|
||||||
ON posts.ID = end_date.post_id
|
LEFT JOIN {$wpdb->prefix}postmeta end_date
|
||||||
AND end_date.meta_key = %s
|
ON posts.ID = end_date.post_id
|
||||||
WHERE posts.post_type = 'shop_subscription'
|
AND end_date.meta_key = %s
|
||||||
AND posts.post_status NOT IN( 'wc-pending', 'trash' )
|
WHERE posts.post_type = 'shop_subscription'
|
||||||
GROUP BY periods_active
|
AND posts.post_status NOT IN( 'wc-pending', 'trash' )
|
||||||
ORDER BY periods_active ASC",
|
GROUP BY periods_active
|
||||||
$days_in_interval_period,
|
ORDER BY periods_active ASC",
|
||||||
( $oldest_subscription_age + 1 ), // Consider living subscriptions as being alive for one period longer than the longest living subsription
|
$days_in_interval_period,
|
||||||
wcs_get_date_meta_key( 'cancelled' ), // If a subscription has a cancelled date, use that to determine a more accurate lifetime
|
( $oldest_subscription_age + 1 ), // Consider living subscriptions as being alive for one period longer than the longest living subscription
|
||||||
wcs_get_date_meta_key( 'end' ) // Otherwise, we want to use the end date for subscritions that have expired
|
wcs_get_date_meta_key( 'cancelled' ), // If a subscription has a cancelled date, use that to determine a more accurate lifetime
|
||||||
|
wcs_get_date_meta_key( 'end' ) // Otherwise, we want to use the end date for subscriptions that have expired
|
||||||
|
),
|
||||||
|
OBJECT_K
|
||||||
);
|
);
|
||||||
|
|
||||||
$subscription_ages = $wpdb->get_results( $base_query, OBJECT_K );
|
|
||||||
|
|
||||||
$this->report_data->total_subscriptions = $this->report_data->unended_subscriptions = absint( array_sum( wp_list_pluck( $subscription_ages, 'count' ) ) );
|
$this->report_data->total_subscriptions = $this->report_data->unended_subscriptions = absint( array_sum( wp_list_pluck( $subscription_ages, 'count' ) ) );
|
||||||
$this->report_data->living_subscriptions = array();
|
$this->report_data->living_subscriptions = array();
|
||||||
|
@@ -121,14 +121,23 @@ class WCS_Report_Subscription_By_Customer extends WP_List_Table {
|
|||||||
|
|
||||||
$this->totals = self::get_data();
|
$this->totals = self::get_data();
|
||||||
|
|
||||||
$customer_query = apply_filters( 'wcs_reports_current_customer_query',
|
$active_statuses = wcs_maybe_prefix_key( apply_filters( 'wcs_reports_active_statuses', [ 'active', 'pending-cancel' ] ), 'wc-' );
|
||||||
"SELECT customer_ids.meta_value as customer_id,
|
$paid_statuses = wcs_maybe_prefix_key( apply_filters( 'woocommerce_reports_paid_order_statuses', [ 'completed', 'processing' ] ), 'wc-' );
|
||||||
|
|
||||||
|
$active_statuses_placeholders = implode( ',', array_fill( 0, count( $active_statuses ), '%s' ) );
|
||||||
|
$paid_statuses_placeholders = implode( ',', array_fill( 0, count( $paid_statuses ), '%s' ) );
|
||||||
|
|
||||||
|
// Ignored for allowing interpolation in the IN statements.
|
||||||
|
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
|
||||||
|
$query = apply_filters( 'wcs_reports_current_customer_query',
|
||||||
|
$wpdb->prepare(
|
||||||
|
"SELECT customer_ids.meta_value as customer_id,
|
||||||
COUNT(subscription_posts.ID) as total_subscriptions,
|
COUNT(subscription_posts.ID) as total_subscriptions,
|
||||||
COALESCE( SUM(parent_total.meta_value), 0) as initial_order_total,
|
COALESCE( SUM(parent_total.meta_value), 0) as initial_order_total,
|
||||||
COUNT(DISTINCT parent_order.ID) as initial_order_count,
|
COUNT(DISTINCT parent_order.ID) as initial_order_count,
|
||||||
SUM(CASE
|
SUM(CASE
|
||||||
WHEN subscription_posts.post_status
|
WHEN subscription_posts.post_status
|
||||||
IN ( 'wc-" . implode( "','wc-", apply_filters( 'wcs_reports_active_statuses', array( 'active', 'pending-cancel' ) ) ) . "' ) THEN 1
|
IN ( {$active_statuses_placeholders} ) THEN 1
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END) AS active_subscriptions
|
END) AS active_subscriptions
|
||||||
FROM {$wpdb->posts} subscription_posts
|
FROM {$wpdb->posts} subscription_posts
|
||||||
@@ -137,7 +146,7 @@ class WCS_Report_Subscription_By_Customer extends WP_List_Table {
|
|||||||
AND customer_ids.meta_key = '_customer_user'
|
AND customer_ids.meta_key = '_customer_user'
|
||||||
LEFT JOIN {$wpdb->posts} parent_order
|
LEFT JOIN {$wpdb->posts} parent_order
|
||||||
ON parent_order.ID = subscription_posts.post_parent
|
ON parent_order.ID = subscription_posts.post_parent
|
||||||
AND parent_order.post_status IN ( 'wc-" . implode( "','wc-", apply_filters( 'woocommerce_reports_paid_order_statuses', array( 'completed', 'processing' ) ) ) . "' )
|
AND parent_order.post_status IN ( {$paid_statuses_placeholders} )
|
||||||
LEFT JOIN {$wpdb->postmeta} parent_total
|
LEFT JOIN {$wpdb->postmeta} parent_total
|
||||||
ON parent_total.post_id = parent_order.ID
|
ON parent_total.post_id = parent_order.ID
|
||||||
AND parent_total.meta_key = '_order_total'
|
AND parent_total.meta_key = '_order_total'
|
||||||
@@ -145,37 +154,54 @@ class WCS_Report_Subscription_By_Customer extends WP_List_Table {
|
|||||||
AND subscription_posts.post_status NOT IN ('wc-pending', 'trash')
|
AND subscription_posts.post_status NOT IN ('wc-pending', 'trash')
|
||||||
GROUP BY customer_ids.meta_value
|
GROUP BY customer_ids.meta_value
|
||||||
ORDER BY customer_id DESC
|
ORDER BY customer_id DESC
|
||||||
LIMIT {$offset}, {$per_page}" );
|
LIMIT %d, %d",
|
||||||
|
array_merge( $active_statuses, $paid_statuses, [ $offset, $per_page ] )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
|
||||||
|
|
||||||
$this->items = $wpdb->get_results( $customer_query );
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
|
$this->items = $wpdb->get_results( $query );
|
||||||
|
|
||||||
|
$customer_ids = wp_list_pluck( $this->items, 'customer_id' );
|
||||||
|
$customer_placeholders = implode( ',', array_fill( 0, count( $customer_ids ), '%s' ) );
|
||||||
|
|
||||||
|
$paid_statuses = wcs_maybe_prefix_key( apply_filters( 'woocommerce_reports_paid_order_statuses', [ 'completed', 'processing' ] ), 'wc-' );
|
||||||
|
$status_placeholders = implode( ',', array_fill( 0, count( $paid_statuses ), '%s' ) );
|
||||||
|
|
||||||
// Now get each customer's renewal and switch total
|
// Now get each customer's renewal and switch total
|
||||||
|
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Ignored for allowing interpolation in the IN statements.
|
||||||
$customer_renewal_switch_total_query = apply_filters( 'wcs_reports_current_customer_renewal_switch_total_query',
|
$customer_renewal_switch_total_query = apply_filters( 'wcs_reports_current_customer_renewal_switch_total_query',
|
||||||
"SELECT
|
$wpdb->prepare(
|
||||||
customer_ids.meta_value as customer_id,
|
"SELECT
|
||||||
COALESCE( SUM(renewal_switch_totals.meta_value), 0) as renewal_switch_total,
|
customer_ids.meta_value as customer_id,
|
||||||
COUNT(DISTINCT renewal_order_posts.ID) as renewal_switch_count
|
COALESCE( SUM(renewal_switch_totals.meta_value), 0) as renewal_switch_total,
|
||||||
FROM {$wpdb->postmeta} renewal_order_ids
|
COUNT(DISTINCT renewal_order_posts.ID) as renewal_switch_count
|
||||||
INNER JOIN {$wpdb->posts} subscription_posts
|
FROM {$wpdb->postmeta} renewal_order_ids
|
||||||
ON renewal_order_ids.meta_value = subscription_posts.ID
|
INNER JOIN {$wpdb->posts} subscription_posts
|
||||||
AND subscription_posts.post_type = 'shop_subscription'
|
ON renewal_order_ids.meta_value = subscription_posts.ID
|
||||||
AND subscription_posts.post_status NOT IN ('wc-pending', 'trash')
|
AND subscription_posts.post_type = 'shop_subscription'
|
||||||
INNER JOIN {$wpdb->postmeta} customer_ids
|
AND subscription_posts.post_status NOT IN ('wc-pending', 'trash')
|
||||||
ON renewal_order_ids.meta_value = customer_ids.post_id
|
INNER JOIN {$wpdb->postmeta} customer_ids
|
||||||
AND customer_ids.meta_key = '_customer_user'
|
ON renewal_order_ids.meta_value = customer_ids.post_id
|
||||||
AND customer_ids.meta_value IN ('" . implode( "','", wp_list_pluck( $this->items, 'customer_id' ) ) . "' )
|
AND customer_ids.meta_key = '_customer_user'
|
||||||
INNER JOIN {$wpdb->posts} renewal_order_posts
|
AND customer_ids.meta_value IN ( {$customer_placeholders} )
|
||||||
ON renewal_order_ids.post_id = renewal_order_posts.ID
|
INNER JOIN {$wpdb->posts} renewal_order_posts
|
||||||
AND renewal_order_posts.post_status IN ( 'wc-" . implode( "','wc-", apply_filters( 'woocommerce_reports_paid_order_statuses', array( 'completed', 'processing' ) ) ) . "' )
|
ON renewal_order_ids.post_id = renewal_order_posts.ID
|
||||||
LEFT JOIN {$wpdb->postmeta} renewal_switch_totals
|
AND renewal_order_posts.post_status IN ( {$status_placeholders} )
|
||||||
ON renewal_switch_totals.post_id = renewal_order_ids.post_id
|
LEFT JOIN {$wpdb->postmeta} renewal_switch_totals
|
||||||
AND renewal_switch_totals.meta_key = '_order_total'
|
ON renewal_switch_totals.post_id = renewal_order_ids.post_id
|
||||||
WHERE renewal_order_ids.meta_key = '_subscription_renewal'
|
AND renewal_switch_totals.meta_key = '_order_total'
|
||||||
OR renewal_order_ids.meta_key = '_subscription_switch'
|
WHERE renewal_order_ids.meta_key = '_subscription_renewal'
|
||||||
GROUP BY customer_id
|
OR renewal_order_ids.meta_key = '_subscription_switch'
|
||||||
ORDER BY customer_id"
|
GROUP BY customer_id
|
||||||
|
ORDER BY customer_id",
|
||||||
|
array_merge( $customer_ids, $paid_statuses )
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare.
|
||||||
|
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$customer_renewal_switch_totals = $wpdb->get_results( $customer_renewal_switch_total_query, OBJECT_K );
|
$customer_renewal_switch_totals = $wpdb->get_results( $customer_renewal_switch_total_query, OBJECT_K );
|
||||||
|
|
||||||
foreach ( $this->items as $index => $item ) {
|
foreach ( $this->items as $index => $item ) {
|
||||||
@@ -212,14 +238,22 @@ class WCS_Report_Subscription_By_Customer extends WP_List_Table {
|
|||||||
$args = apply_filters( 'wcs_reports_customer_total_args', $args );
|
$args = apply_filters( 'wcs_reports_customer_total_args', $args );
|
||||||
$args = wp_parse_args( $args, $default_args );
|
$args = wp_parse_args( $args, $default_args );
|
||||||
|
|
||||||
|
$active_statuses = wcs_maybe_prefix_key( apply_filters( 'wcs_reports_active_statuses', [ 'active', 'pending-cancel' ] ), 'wc-' );
|
||||||
|
$order_statuses = wcs_maybe_prefix_key( $args['order_status'], 'wc-' );
|
||||||
|
|
||||||
|
$active_statuses_placeholders = implode( ',', array_fill( 0, count( $active_statuses ), '%s' ) );
|
||||||
|
$order_statuses_placeholders = implode( ',', array_fill( 0, count( $order_statuses ), '%s' ) );
|
||||||
|
|
||||||
$total_query = apply_filters( 'wcs_reports_customer_total_query',
|
$total_query = apply_filters( 'wcs_reports_customer_total_query',
|
||||||
"SELECT COUNT( DISTINCT customer_ids.meta_value) as total_customers,
|
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Ignored for allowing interpolation in the IN statements.
|
||||||
|
$wpdb->prepare(
|
||||||
|
"SELECT COUNT( DISTINCT customer_ids.meta_value) as total_customers,
|
||||||
COUNT(subscription_posts.ID) as total_subscriptions,
|
COUNT(subscription_posts.ID) as total_subscriptions,
|
||||||
COALESCE( SUM(parent_total.meta_value), 0) as initial_order_total,
|
COALESCE( SUM(parent_total.meta_value), 0) as initial_order_total,
|
||||||
COUNT(DISTINCT parent_order.ID) as initial_order_count,
|
COUNT(DISTINCT parent_order.ID) as initial_order_count,
|
||||||
COALESCE(SUM(CASE
|
COALESCE(SUM(CASE
|
||||||
WHEN subscription_posts.post_status
|
WHEN subscription_posts.post_status
|
||||||
IN ( 'wc-" . implode( "','wc-", apply_filters( 'wcs_reports_active_statuses', array( 'active', 'pending-cancel' ) ) ) . "' ) THEN 1
|
IN ( {$active_statuses_placeholders} ) THEN 1
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END), 0) AS active_subscriptions
|
END), 0) AS active_subscriptions
|
||||||
FROM {$wpdb->posts} subscription_posts
|
FROM {$wpdb->posts} subscription_posts
|
||||||
@@ -228,13 +262,16 @@ class WCS_Report_Subscription_By_Customer extends WP_List_Table {
|
|||||||
AND customer_ids.meta_key = '_customer_user'
|
AND customer_ids.meta_key = '_customer_user'
|
||||||
LEFT JOIN {$wpdb->posts} parent_order
|
LEFT JOIN {$wpdb->posts} parent_order
|
||||||
ON parent_order.ID = subscription_posts.post_parent
|
ON parent_order.ID = subscription_posts.post_parent
|
||||||
AND parent_order.post_status IN ( 'wc-" . implode( "','wc-", $args['order_status'] ) . "' )
|
AND parent_order.post_status IN ( {$order_statuses_placeholders} )
|
||||||
LEFT JOIN {$wpdb->postmeta} parent_total
|
LEFT JOIN {$wpdb->postmeta} parent_total
|
||||||
ON parent_total.post_id = parent_order.ID
|
ON parent_total.post_id = parent_order.ID
|
||||||
AND parent_total.meta_key = '_order_total'
|
AND parent_total.meta_key = '_order_total'
|
||||||
WHERE subscription_posts.post_type = 'shop_subscription'
|
WHERE subscription_posts.post_type = 'shop_subscription'
|
||||||
AND subscription_posts.post_status NOT IN ('wc-pending', 'trash')
|
AND subscription_posts.post_status NOT IN ('wc-pending', 'trash')
|
||||||
");
|
",
|
||||||
|
array_merge( $active_statuses, $order_statuses )
|
||||||
|
) );
|
||||||
|
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared.
|
||||||
|
|
||||||
$cached_results = get_transient( strtolower( __CLASS__ ) );
|
$cached_results = get_transient( strtolower( __CLASS__ ) );
|
||||||
$query_hash = md5( $total_query );
|
$query_hash = md5( $total_query );
|
||||||
@@ -247,35 +284,45 @@ class WCS_Report_Subscription_By_Customer extends WP_List_Table {
|
|||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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 ) );
|
||||||
set_transient( strtolower( __CLASS__ ), $cached_results, WEEK_IN_SECONDS );
|
set_transient( strtolower( __CLASS__ ), $cached_results, WEEK_IN_SECONDS );
|
||||||
}
|
}
|
||||||
|
|
||||||
$customer_totals = $cached_results[ $query_hash ];
|
$customer_totals = $cached_results[ $query_hash ];
|
||||||
|
|
||||||
|
$status_placeholders = implode( ',', array_fill( 0, count( $args['order_status'] ), '%s' ) );
|
||||||
|
$statuses = wcs_maybe_prefix_key( $args['order_status'], 'wc-' );
|
||||||
|
|
||||||
$renewal_switch_total_query = apply_filters( 'wcs_reports_customer_total_renewal_switch_query',
|
$renewal_switch_total_query = apply_filters( 'wcs_reports_customer_total_renewal_switch_query',
|
||||||
"SELECT COALESCE( SUM(renewal_switch_totals.meta_value), 0) as renewal_switch_total,
|
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Ignored for allowing interpolation in the IN statements.
|
||||||
COUNT(DISTINCT renewal_order_posts.ID) as renewal_switch_count
|
$wpdb->prepare(
|
||||||
FROM {$wpdb->postmeta} renewal_order_ids
|
"SELECT COALESCE( SUM(renewal_switch_totals.meta_value), 0) as renewal_switch_total,
|
||||||
INNER JOIN {$wpdb->posts} subscription_posts
|
COUNT(DISTINCT renewal_order_posts.ID) as renewal_switch_count
|
||||||
|
FROM {$wpdb->postmeta} renewal_order_ids
|
||||||
|
INNER JOIN {$wpdb->posts} subscription_posts
|
||||||
ON renewal_order_ids.meta_value = subscription_posts.ID
|
ON renewal_order_ids.meta_value = subscription_posts.ID
|
||||||
AND subscription_posts.post_type = 'shop_subscription'
|
AND subscription_posts.post_type = 'shop_subscription'
|
||||||
AND subscription_posts.post_status NOT IN ('wc-pending', 'trash')
|
AND subscription_posts.post_status NOT IN ('wc-pending', 'trash')
|
||||||
INNER JOIN {$wpdb->posts} renewal_order_posts
|
INNER JOIN {$wpdb->posts} renewal_order_posts
|
||||||
ON renewal_order_ids.post_id = renewal_order_posts.ID
|
ON renewal_order_ids.post_id = renewal_order_posts.ID
|
||||||
AND renewal_order_posts.post_status IN ( 'wc-" . implode( "','wc-", $args['order_status'] ) . "' )
|
AND renewal_order_posts.post_status IN ( {$status_placeholders} )
|
||||||
LEFT JOIN {$wpdb->postmeta} renewal_switch_totals
|
LEFT JOIN {$wpdb->postmeta} renewal_switch_totals
|
||||||
ON renewal_switch_totals.post_id = renewal_order_ids.post_id
|
ON renewal_switch_totals.post_id = renewal_order_ids.post_id
|
||||||
AND renewal_switch_totals.meta_key = '_order_total'
|
AND renewal_switch_totals.meta_key = '_order_total'
|
||||||
WHERE renewal_order_ids.meta_key = '_subscription_renewal'
|
WHERE renewal_order_ids.meta_key = '_subscription_renewal'
|
||||||
OR renewal_order_ids.meta_key = '_subscription_switch'"
|
OR renewal_order_ids.meta_key = '_subscription_switch'",
|
||||||
|
$statuses
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared.
|
||||||
|
|
||||||
$query_hash = md5( $renewal_switch_total_query );
|
$query_hash = md5( $renewal_switch_total_query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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 ) );
|
||||||
set_transient( strtolower( __CLASS__ ), $cached_results, WEEK_IN_SECONDS );
|
set_transient( strtolower( __CLASS__ ), $cached_results, WEEK_IN_SECONDS );
|
||||||
}
|
}
|
||||||
|
@@ -168,6 +168,7 @@ class WCS_Report_Subscription_By_Product extends WP_List_Table {
|
|||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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 );
|
||||||
}
|
}
|
||||||
@@ -201,26 +202,36 @@ class WCS_Report_Subscription_By_Product extends WP_List_Table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$placeholders = implode( ',', array_fill( 0, count( $args['order_status'] ), '%s' ) );
|
||||||
|
$statuses = wcs_maybe_prefix_key( $args['order_status'], 'wc-' );
|
||||||
|
|
||||||
// Now let's get the total revenue for each product so we can provide an average lifetime value for that product
|
// Now let's get the total revenue for each product so we can provide an average lifetime value for that product
|
||||||
$query = apply_filters( 'wcs_reports_product_lifetime_value_query',
|
$query = apply_filters( 'wcs_reports_product_lifetime_value_query',
|
||||||
"SELECT wcoimeta.meta_value as product_id, SUM(wcoimeta2.meta_value) as product_total
|
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Ignored for allowing interpolation in the IN statements.
|
||||||
|
$wpdb->prepare(
|
||||||
|
"SELECT wcoimeta.meta_value as product_id, SUM(wcoimeta2.meta_value) as product_total
|
||||||
FROM {$wpdb->prefix}woocommerce_order_items AS wcoitems
|
FROM {$wpdb->prefix}woocommerce_order_items AS wcoitems
|
||||||
INNER JOIN {$wpdb->posts} AS wcorders
|
INNER JOIN {$wpdb->posts} AS wcorders
|
||||||
ON wcoitems.order_id = wcorders.ID
|
ON wcoitems.order_id = wcorders.ID
|
||||||
AND wcorders.post_type = 'shop_order'
|
AND wcorders.post_type = 'shop_order'
|
||||||
AND wcorders.post_status IN ( 'wc-" . implode( "','wc-", $args['order_status'] ) . "' )
|
AND wcorders.post_status IN ( {$placeholders} )
|
||||||
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS wcoimeta
|
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS wcoimeta
|
||||||
ON wcoimeta.order_item_id = wcoitems.order_item_id
|
ON wcoimeta.order_item_id = wcoitems.order_item_id
|
||||||
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS wcoimeta2
|
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS wcoimeta2
|
||||||
ON wcoimeta2.order_item_id = wcoitems.order_item_id
|
ON wcoimeta2.order_item_id = wcoitems.order_item_id
|
||||||
WHERE ( wcoimeta.meta_key = '_product_id' OR wcoimeta.meta_key = '_variation_id' )
|
WHERE ( wcoimeta.meta_key = '_product_id' OR wcoimeta.meta_key = '_variation_id' )
|
||||||
AND wcoimeta2.meta_key = '_line_total'
|
AND wcoimeta2.meta_key = '_line_total'
|
||||||
GROUP BY product_id" );
|
GROUP BY product_id",
|
||||||
|
$statuses
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
|
||||||
|
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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 );
|
||||||
}
|
}
|
||||||
|
@@ -282,9 +282,15 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$statuses = wcs_maybe_prefix_key( $args['order_status'], 'wc-' );
|
||||||
|
$order_types = wc_get_order_types( 'order-count' );
|
||||||
|
$status_placeholders = implode( ', ', array_fill( 0, count( $args['order_status'] ), '%s' ) );
|
||||||
|
$order_types_placeholders = implode( ', ', array_fill( 0, count( $order_types ), '%s' ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* New subscription orders
|
* New subscription orders
|
||||||
*/
|
*/
|
||||||
|
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Ignored for allowing interpolation in the IN statements.
|
||||||
$query = $wpdb->prepare(
|
$query = $wpdb->prepare(
|
||||||
"SELECT SUM(subscriptions.count) as count,
|
"SELECT SUM(subscriptions.count) as count,
|
||||||
order_posts.post_date as post_date,
|
order_posts.post_date as post_date,
|
||||||
@@ -304,23 +310,27 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
) AS subscriptions ON subscriptions.order_id = order_posts.ID
|
) AS subscriptions ON subscriptions.order_id = order_posts.ID
|
||||||
LEFT JOIN {$wpdb->postmeta} AS order_total_post_meta
|
LEFT JOIN {$wpdb->postmeta} AS order_total_post_meta
|
||||||
ON order_posts.ID = order_total_post_meta.post_id
|
ON order_posts.ID = order_total_post_meta.post_id
|
||||||
WHERE order_posts.post_type IN ( '" . implode( "','", wc_get_order_types( 'order-count' ) ) . "' )
|
WHERE order_posts.post_type IN ( {$order_types_placeholders} )
|
||||||
AND order_posts.post_status IN ( 'wc-" . implode( "','wc-", $args['order_status'] ) . "' )
|
AND order_posts.post_status IN ( {$status_placeholders} )
|
||||||
AND order_posts.post_date >= %s
|
AND order_posts.post_date >= %s
|
||||||
AND order_posts.post_date < %s
|
AND order_posts.post_date < %s
|
||||||
AND order_total_post_meta.meta_key = '_order_total'
|
AND order_total_post_meta.meta_key = '_order_total'
|
||||||
GROUP BY YEAR(order_posts.post_date), MONTH(order_posts.post_date), DAY(order_posts.post_date)
|
GROUP BY YEAR(order_posts.post_date), MONTH(order_posts.post_date), DAY(order_posts.post_date)
|
||||||
ORDER BY post_date ASC",
|
ORDER BY post_date ASC",
|
||||||
date( 'Y-m-d', $this->start_date ),
|
array_merge(
|
||||||
$query_end_date,
|
[ date( 'Y-m-d', $this->start_date ), $query_end_date ],
|
||||||
date( 'Y-m-d', $this->start_date ),
|
$order_types,
|
||||||
$query_end_date
|
$statuses,
|
||||||
|
[ date( 'Y-m-d', $this->start_date ), $query_end_date ]
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
// phpcs:enable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||||
|
|
||||||
$query_hash = md5( $query );
|
$query_hash = md5( $query );
|
||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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;
|
||||||
}
|
}
|
||||||
@@ -364,7 +374,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
) searchdate,
|
) searchdate,
|
||||||
{$wpdb->posts} AS wcsubs,
|
{$wpdb->posts} AS wcsubs,
|
||||||
{$wpdb->postmeta} AS wcsmeta
|
{$wpdb->postmeta} AS wcsmeta
|
||||||
WHERE wcsubs.ID = wcsmeta.post_id AND wcsmeta.meta_key = '%s'
|
WHERE wcsubs.ID = wcsmeta.post_id AND wcsmeta.meta_key = %s
|
||||||
AND DATE( wcsubs.post_date ) <= searchdate.Date
|
AND DATE( wcsubs.post_date ) <= searchdate.Date
|
||||||
AND wcsubs.post_type IN ( 'shop_subscription' )
|
AND wcsubs.post_type IN ( 'shop_subscription' )
|
||||||
AND wcsubs.post_status NOT IN( 'auto-draft' )
|
AND wcsubs.post_status NOT IN( 'auto-draft' )
|
||||||
@@ -386,6 +396,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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;
|
||||||
}
|
}
|
||||||
@@ -397,7 +408,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
* Subscription cancellations
|
* Subscription cancellations
|
||||||
*/
|
*/
|
||||||
$query = $wpdb->prepare(
|
$query = $wpdb->prepare(
|
||||||
"SELECT COUNT( DISTINCT wcsubs.ID ) as count, CONVERT_TZ( wcsmeta_cancel.meta_value, '+00:00', '{$site_timezone}' ) as cancel_date, GROUP_CONCAT( DISTINCT wcsubs.ID ) as subscription_ids
|
"SELECT COUNT( DISTINCT wcsubs.ID ) as count, CONVERT_TZ( wcsmeta_cancel.meta_value, '+00:00', %s ) as cancel_date, GROUP_CONCAT( DISTINCT wcsubs.ID ) as subscription_ids
|
||||||
FROM {$wpdb->posts} as wcsubs
|
FROM {$wpdb->posts} as wcsubs
|
||||||
JOIN {$wpdb->postmeta} AS wcsmeta_cancel
|
JOIN {$wpdb->postmeta} AS wcsmeta_cancel
|
||||||
ON wcsubs.ID = wcsmeta_cancel.post_id
|
ON wcsubs.ID = wcsmeta_cancel.post_id
|
||||||
@@ -406,6 +417,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
GROUP BY YEAR( cancel_date ), MONTH( cancel_date ), DAY( cancel_date )
|
GROUP BY YEAR( cancel_date ), MONTH( cancel_date ), DAY( cancel_date )
|
||||||
HAVING cancel_date BETWEEN %s AND %s
|
HAVING cancel_date BETWEEN %s AND %s
|
||||||
ORDER BY wcsmeta_cancel.meta_value ASC",
|
ORDER BY wcsmeta_cancel.meta_value ASC",
|
||||||
|
$site_timezone,
|
||||||
wcs_get_date_meta_key( 'cancelled' ),
|
wcs_get_date_meta_key( 'cancelled' ),
|
||||||
date( 'Y-m-d', $this->start_date ),
|
date( 'Y-m-d', $this->start_date ),
|
||||||
$query_end_date
|
$query_end_date
|
||||||
@@ -415,6 +427,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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;
|
||||||
}
|
}
|
||||||
@@ -427,7 +440,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
* Subscriptions ended
|
* Subscriptions ended
|
||||||
*/
|
*/
|
||||||
$query = $wpdb->prepare(
|
$query = $wpdb->prepare(
|
||||||
"SELECT COUNT( DISTINCT wcsubs.ID ) as count, CONVERT_TZ( wcsmeta_end.meta_value, '+00:00', '{$site_timezone}' ) as end_date, GROUP_CONCAT( DISTINCT wcsubs.ID ) as subscription_ids
|
"SELECT COUNT( DISTINCT wcsubs.ID ) as count, CONVERT_TZ( wcsmeta_end.meta_value, '+00:00', %s ) as end_date, GROUP_CONCAT( DISTINCT wcsubs.ID ) as subscription_ids
|
||||||
FROM {$wpdb->posts} as wcsubs
|
FROM {$wpdb->posts} as wcsubs
|
||||||
JOIN {$wpdb->postmeta} AS wcsmeta_end
|
JOIN {$wpdb->postmeta} AS wcsmeta_end
|
||||||
ON wcsubs.ID = wcsmeta_end.post_id
|
ON wcsubs.ID = wcsmeta_end.post_id
|
||||||
@@ -436,6 +449,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
GROUP BY YEAR( end_date ), MONTH( end_date ), DAY( end_date )
|
GROUP BY YEAR( end_date ), MONTH( end_date ), DAY( end_date )
|
||||||
HAVING end_date BETWEEN %s AND %s
|
HAVING end_date BETWEEN %s AND %s
|
||||||
ORDER BY wcsmeta_end.meta_value ASC",
|
ORDER BY wcsmeta_end.meta_value ASC",
|
||||||
|
$site_timezone,
|
||||||
wcs_get_date_meta_key( 'end' ),
|
wcs_get_date_meta_key( 'end' ),
|
||||||
date( 'Y-m-d', $this->start_date ),
|
date( 'Y-m-d', $this->start_date ),
|
||||||
$query_end_date
|
$query_end_date
|
||||||
@@ -445,6 +459,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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;
|
||||||
}
|
}
|
||||||
|
@@ -56,40 +56,46 @@ class WCS_Report_Subscription_Payment_Retry extends WC_Admin_Report {
|
|||||||
$query_end_date = get_gmt_from_date( date( 'Y-m-d H:i:s', wcs_strtotime_dark_knight( '+1 day', $this->end_date ) ) );
|
$query_end_date = get_gmt_from_date( date( 'Y-m-d H:i:s', wcs_strtotime_dark_knight( '+1 day', $this->end_date ) ) );
|
||||||
|
|
||||||
// Get the sum of order totals for completed retries (i.e. retries which eventually succeeded in processing the failed payment)
|
// Get the sum of order totals for completed retries (i.e. retries which eventually succeeded in processing the failed payment)
|
||||||
$renewal_query = $wpdb->prepare(
|
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- The $this->group_by_query clause is hard coded.
|
||||||
"
|
$this->report_data->renewal_data = $wpdb->get_results(
|
||||||
SELECT COUNT(DISTINCT retries.retry_id) as count, MIN(retries.date_gmt) AS retry_date_gmt, MIN({$retry_date_in_local_time}) AS retry_date, SUM(meta_order_total.meta_value) AS renewal_totals
|
$wpdb->prepare(
|
||||||
FROM {$wpdb->posts} AS orders
|
"
|
||||||
INNER JOIN {$wpdb->prefix}wcs_payment_retries AS retries ON ( orders.ID = retries.order_id )
|
SELECT COUNT(DISTINCT retries.retry_id) as count, MIN(retries.date_gmt) AS retry_date_gmt, MIN(%s) AS retry_date, SUM(meta_order_total.meta_value) AS renewal_totals
|
||||||
LEFT JOIN {$wpdb->postmeta} AS meta_order_total ON ( orders.ID = meta_order_total.post_id AND meta_order_total.meta_key = '_order_total' )
|
FROM {$wpdb->posts} AS orders
|
||||||
WHERE retries.status = 'complete'
|
INNER JOIN {$wpdb->prefix}wcs_payment_retries AS retries ON ( orders.ID = retries.order_id )
|
||||||
AND retries.date_gmt >= %s
|
LEFT JOIN {$wpdb->postmeta} AS meta_order_total ON ( orders.ID = meta_order_total.post_id AND meta_order_total.meta_key = '_order_total' )
|
||||||
AND retries.date_gmt < %s
|
WHERE retries.status = 'complete'
|
||||||
GROUP BY {$this->group_by_query}
|
AND retries.date_gmt >= %s
|
||||||
ORDER BY retry_date_gmt ASC
|
AND retries.date_gmt < %s
|
||||||
",
|
GROUP BY {$this->group_by_query}
|
||||||
$query_start_date,
|
ORDER BY retry_date_gmt ASC
|
||||||
$query_end_date
|
",
|
||||||
|
$retry_date_in_local_time,
|
||||||
|
$query_start_date,
|
||||||
|
$query_end_date
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||||
$this->report_data->renewal_data = $wpdb->get_results( $renewal_query );
|
|
||||||
|
|
||||||
// Get the counts for all retries, grouped by day or month and status
|
// Get the counts for all retries, grouped by day or month and status
|
||||||
$retry_query = $wpdb->prepare(
|
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- The $this->group_by_query clause is hard coded.
|
||||||
"
|
$this->report_data->retry_data = $wpdb->get_results(
|
||||||
SELECT COUNT(DISTINCT retries.retry_id) AS count, retries.status AS status, MIN(retries.date_gmt) AS retry_date_gmt, MIN({$retry_date_in_local_time}) AS retry_date
|
$wpdb->prepare(
|
||||||
FROM {$wpdb->prefix}wcs_payment_retries AS retries
|
"
|
||||||
WHERE retries.status IN ( 'complete', 'failed', 'pending' )
|
SELECT COUNT(DISTINCT retries.retry_id) AS count, retries.status AS status, MIN(retries.date_gmt) AS retry_date_gmt, MIN(%s) AS retry_date
|
||||||
AND retries.date_gmt >= %s
|
FROM {$wpdb->prefix}wcs_payment_retries AS retries
|
||||||
AND retries.date_gmt < %s
|
WHERE retries.status IN ( 'complete', 'failed', 'pending' )
|
||||||
GROUP BY {$this->group_by_query}, status
|
AND retries.date_gmt >= %s
|
||||||
ORDER BY retry_date_gmt ASC
|
AND retries.date_gmt < %s
|
||||||
",
|
GROUP BY {$this->group_by_query}, status
|
||||||
$query_start_date,
|
ORDER BY retry_date_gmt ASC
|
||||||
$query_end_date
|
",
|
||||||
|
$retry_date_in_local_time,
|
||||||
|
$query_start_date,
|
||||||
|
$query_end_date
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||||
$this->report_data->retry_data = $wpdb->get_results( $retry_query );
|
|
||||||
|
|
||||||
// Total up the query data
|
// Total up the query data
|
||||||
$this->report_data->retry_failed_count = absint( array_sum( wp_list_pluck( wp_list_filter( $this->report_data->retry_data, array( 'status' => 'failed' ) ), 'count' ) ) );
|
$this->report_data->retry_failed_count = absint( array_sum( wp_list_pluck( wp_list_filter( $this->report_data->retry_data, array( 'status' => 'failed' ) ), 'count' ) ) );
|
||||||
|
@@ -130,6 +130,7 @@ class WCS_Report_Upcoming_Recurring_Revenue extends WC_Admin_Report {
|
|||||||
$args = wp_parse_args( $args, $default_args );
|
$args = wp_parse_args( $args, $default_args );
|
||||||
|
|
||||||
// Query based on whole days, not minutes/hours so that we can cache the query for at least 24 hours
|
// Query based on whole days, not minutes/hours so that we can cache the query for at least 24 hours
|
||||||
|
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- The $this->group_by_query clause is hard coded.
|
||||||
$base_query = $wpdb->prepare(
|
$base_query = $wpdb->prepare(
|
||||||
"SELECT
|
"SELECT
|
||||||
DATE(ms.meta_value) as scheduled_date,
|
DATE(ms.meta_value) as scheduled_date,
|
||||||
@@ -155,7 +156,7 @@ class WCS_Report_Upcoming_Recurring_Revenue extends WC_Admin_Report {
|
|||||||
AND p.post_status = 'wc-active'
|
AND p.post_status = 'wc-active'
|
||||||
AND mo.meta_key = '_order_total'
|
AND mo.meta_key = '_order_total'
|
||||||
AND ms.meta_key = '_schedule_next_payment'
|
AND ms.meta_key = '_schedule_next_payment'
|
||||||
AND ( ( ms.meta_value < '%s' AND me.meta_value = 0 ) OR ( me.meta_value > '%s' AND ms.meta_value < '%s' ) )
|
AND ( ( ms.meta_value < %s AND me.meta_value = 0 ) OR ( me.meta_value > %s AND ms.meta_value < %s ) )
|
||||||
AND mi.meta_key = '_billing_interval'
|
AND mi.meta_key = '_billing_interval'
|
||||||
AND mp.meta_key = '_billing_period'
|
AND mp.meta_key = '_billing_period'
|
||||||
AND me.meta_key = '_schedule_end '
|
AND me.meta_key = '_schedule_end '
|
||||||
@@ -165,6 +166,7 @@ class WCS_Report_Upcoming_Recurring_Revenue extends WC_Admin_Report {
|
|||||||
date( 'Y-m-d', $this->start_date ),
|
date( 'Y-m-d', $this->start_date ),
|
||||||
date( 'Y-m-d', strtotime( '+1 DAY', $this->end_date ) )
|
date( 'Y-m-d', strtotime( '+1 DAY', $this->end_date ) )
|
||||||
);
|
);
|
||||||
|
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||||
|
|
||||||
$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 );
|
||||||
@@ -176,6 +178,7 @@ class WCS_Report_Upcoming_Recurring_Revenue extends WC_Admin_Report {
|
|||||||
|
|
||||||
if ( $args['no_cache'] || ! 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' );
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This query is prepared above.
|
||||||
$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 );
|
||||||
}
|
}
|
||||||
|
@@ -148,7 +148,7 @@ class WCS_Early_Renewal_Modal_Handler {
|
|||||||
if ( $renewal_order->needs_payment() ) {
|
if ( $renewal_order->needs_payment() ) {
|
||||||
$renewal_order->delete( true );
|
$renewal_order->delete( true );
|
||||||
wc_add_notice( __( 'Payment for the renewal order was unsuccessful with your payment method on file, please try again.', 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( __( 'Payment for the renewal order was unsuccessful with your payment method on file, please try again.', 'woocommerce-subscriptions' ), 'error' );
|
||||||
wp_redirect( wcs_get_early_renewal_url( $subscription ) );
|
wp_safe_redirect( wcs_get_early_renewal_url( $subscription ) );
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ class WCS_Early_Renewal_Modal_Handler {
|
|||||||
* @since 2.6.0
|
* @since 2.6.0
|
||||||
*/
|
*/
|
||||||
private static function redirect() {
|
private static function redirect() {
|
||||||
wp_redirect( remove_query_arg( array( 'process_early_renewal', 'subscription_id', 'wcs_nonce' ) ) );
|
wp_safe_redirect( remove_query_arg( array( 'process_early_renewal', 'subscription_id', 'wcs_nonce' ) ) );
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -94,7 +94,8 @@ class WCS_Retry_Database_Store extends WCS_Retry_Store {
|
|||||||
$retry = null;
|
$retry = null;
|
||||||
$raw_retry = $wpdb->get_row(
|
$raw_retry = $wpdb->get_row(
|
||||||
$wpdb->prepare(
|
$wpdb->prepare(
|
||||||
"SELECT * FROM {$this->get_full_table_name()} WHERE retry_id = %d LIMIT 1",
|
"SELECT * FROM %i WHERE retry_id = %d LIMIT 1",
|
||||||
|
$this->get_full_table_name(),
|
||||||
$retry_id
|
$retry_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -183,8 +184,11 @@ class WCS_Retry_Database_Store extends WCS_Retry_Store {
|
|||||||
$orderby = sprintf( ' ORDER BY %s', sanitize_sql_orderby( "{$args['orderby']} {$args['order']}" ) );
|
$orderby = sprintf( ' ORDER BY %s', sanitize_sql_orderby( "{$args['orderby']} {$args['order']}" ) );
|
||||||
$limit = ( $args['limit'] > 0 ) ? $wpdb->prepare( ' LIMIT %d', $args['limit'] ) : '';
|
$limit = ( $args['limit'] > 0 ) ? $wpdb->prepare( ' LIMIT %d', $args['limit'] ) : '';
|
||||||
|
|
||||||
$raw_retries = $wpdb->get_results( "SELECT * FROM {$this->get_full_table_name()} $where $orderby $limit" );
|
|
||||||
$retries = array();
|
$retries = array();
|
||||||
|
$raw_retries = $wpdb->get_results(
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- The subqueries are prepared above.
|
||||||
|
$wpdb->prepare( "SELECT * FROM %i $where $orderby $limit", $this->get_full_table_name() )
|
||||||
|
);
|
||||||
|
|
||||||
foreach ( $raw_retries as $raw_retry ) {
|
foreach ( $raw_retries as $raw_retry ) {
|
||||||
if ( 'ids' === $return ) {
|
if ( 'ids' === $return ) {
|
||||||
|
@@ -183,12 +183,13 @@ class WC_Subscriptions_Switcher {
|
|||||||
if ( isset( $_GET['switch-subscription'] ) && isset( $_GET['item'] ) ) {
|
if ( isset( $_GET['switch-subscription'] ) && isset( $_GET['item'] ) ) {
|
||||||
|
|
||||||
$subscription = wcs_get_subscription( absint( $_GET['switch-subscription'] ) );
|
$subscription = wcs_get_subscription( absint( $_GET['switch-subscription'] ) );
|
||||||
$line_item = wcs_get_order_item( absint( $_GET['item'] ), $subscription );
|
$line_item = $subscription ? wcs_get_order_item( absint( $_GET['item'] ), $subscription ) : false;
|
||||||
|
$nonce = ! empty( $_GET['_wcsnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wcsnonce'] ) ) : false;
|
||||||
|
|
||||||
// Visiting a switch link for someone elses subscription or if the switch link doesn't contain a valid nonce
|
// Visiting a switch link for someone elses subscription or if the switch link doesn't contain a valid nonce
|
||||||
if ( ! is_object( $subscription ) || empty( $_GET['_wcsnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wcsnonce'] ) ), 'wcs_switch_request' ) || empty( $line_item ) || ! self::can_item_be_switched_by_user( $line_item, $subscription ) ) {
|
if ( ! is_object( $subscription ) || empty( $nonce ) || ! wp_verify_nonce( $nonce, 'wcs_switch_request' ) || empty( $line_item ) || ! self::can_item_be_switched_by_user( $line_item, $subscription ) ) {
|
||||||
|
|
||||||
wp_redirect( remove_query_arg( array( 'switch-subscription', 'auto-switch', 'item', '_wcsnonce' ) ) );
|
wp_safe_redirect( remove_query_arg( array( 'switch-subscription', 'auto-switch', 'item', '_wcsnonce' ) ) );
|
||||||
exit();
|
exit();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -238,7 +239,7 @@ class WC_Subscriptions_Switcher {
|
|||||||
if ( $removed_item_count > 0 ) {
|
if ( $removed_item_count > 0 ) {
|
||||||
wc_add_notice( _n( 'Your cart contained an invalid subscription switch request. It has been removed.', 'Your cart contained invalid subscription switch requests. They have been removed.', $removed_item_count, 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( _n( 'Your cart contained an invalid subscription switch request. It has been removed.', 'Your cart contained invalid subscription switch requests. They have been removed.', $removed_item_count, 'woocommerce-subscriptions' ), 'error' );
|
||||||
|
|
||||||
wp_redirect( wc_get_cart_url() );
|
wp_safe_redirect( wc_get_cart_url() );
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
} elseif ( is_product() && $product = wc_get_product( $post ) ) { // Automatically initiate the switch process for limited variable subscriptions
|
} elseif ( is_product() && $product = wc_get_product( $post ) ) { // Automatically initiate the switch process for limited variable subscriptions
|
||||||
@@ -305,7 +306,7 @@ class WC_Subscriptions_Switcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( apply_filters( 'wcs_initiate_auto_switch', self::can_item_be_switched_by_user( $item, $subscription ), $item, $subscription ) ) {
|
if ( apply_filters( 'wcs_initiate_auto_switch', self::can_item_be_switched_by_user( $item, $subscription ), $item, $subscription ) ) {
|
||||||
wp_redirect( add_query_arg( 'auto-switch', 'true', self::get_switch_url( $item_id, $item, $subscription ) ) );
|
wp_safe_redirect( add_query_arg( 'auto-switch', 'true', self::get_switch_url( $item_id, $item, $subscription ) ) );
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1456,7 +1457,7 @@ class WC_Subscriptions_Switcher {
|
|||||||
if ( ! current_user_can( 'switch_shop_subscription', $subscription->get_id() ) ) {
|
if ( ! current_user_can( 'switch_shop_subscription', $subscription->get_id() ) ) {
|
||||||
wc_add_notice( __( 'You can not switch this subscription. It appears you do not own the subscription.', 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( __( 'You can not switch this subscription. It appears you do not own the subscription.', 'woocommerce-subscriptions' ), 'error' );
|
||||||
WC()->cart->empty_cart( true );
|
WC()->cart->empty_cart( true );
|
||||||
wp_redirect( get_permalink( $product_id ) );
|
wp_safe_redirect( get_permalink( $product_id ) );
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1497,7 +1498,7 @@ class WC_Subscriptions_Switcher {
|
|||||||
|
|
||||||
wc_add_notice( __( 'There was an error locating the switch details.', 'woocommerce-subscriptions' ), 'error' );
|
wc_add_notice( __( 'There was an error locating the switch details.', 'woocommerce-subscriptions' ), 'error' );
|
||||||
WC()->cart->empty_cart( true );
|
WC()->cart->empty_cart( true );
|
||||||
wp_redirect( get_permalink( wc_get_page_id( 'cart' ) ) );
|
wp_safe_redirect( get_permalink( wc_get_page_id( 'cart' ) ) );
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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 ComposerAutoloaderInitdf568b8a1948145d8f675fb08a939b09::getLoader();
|
return ComposerAutoloaderInit99add140caccae6adfad678f070ccf26::getLoader();
|
||||||
|
11
vendor/composer/InstalledVersions.php
vendored
11
vendor/composer/InstalledVersions.php
vendored
@@ -322,6 +322,7 @@ class InstalledVersions
|
|||||||
}
|
}
|
||||||
|
|
||||||
$installed = array();
|
$installed = array();
|
||||||
|
$copiedLocalDir = false;
|
||||||
|
|
||||||
if (self::$canGetVendors) {
|
if (self::$canGetVendors) {
|
||||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||||
@@ -330,9 +331,11 @@ class InstalledVersions
|
|||||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||||
$required = require $vendorDir.'/composer/installed.php';
|
$required = require $vendorDir.'/composer/installed.php';
|
||||||
$installed[] = self::$installedByVendor[$vendorDir] = $required;
|
self::$installedByVendor[$vendorDir] = $required;
|
||||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
$installed[] = $required;
|
||||||
self::$installed = $installed[count($installed) - 1];
|
if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||||
|
self::$installed = $required;
|
||||||
|
$copiedLocalDir = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -350,7 +353,7 @@ class InstalledVersions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self::$installed !== array()) {
|
if (self::$installed !== array() && !$copiedLocalDir) {
|
||||||
$installed[] = self::$installed;
|
$installed[] = self::$installed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 ComposerAutoloaderInitdf568b8a1948145d8f675fb08a939b09
|
class ComposerAutoloaderInit99add140caccae6adfad678f070ccf26
|
||||||
{
|
{
|
||||||
private static $loader;
|
private static $loader;
|
||||||
|
|
||||||
@@ -24,12 +24,12 @@ class ComposerAutoloaderInitdf568b8a1948145d8f675fb08a939b09
|
|||||||
|
|
||||||
require __DIR__ . '/platform_check.php';
|
require __DIR__ . '/platform_check.php';
|
||||||
|
|
||||||
spl_autoload_register(array('ComposerAutoloaderInitdf568b8a1948145d8f675fb08a939b09', 'loadClassLoader'), true, true);
|
spl_autoload_register(array('ComposerAutoloaderInit99add140caccae6adfad678f070ccf26', '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('ComposerAutoloaderInitdf568b8a1948145d8f675fb08a939b09', 'loadClassLoader'));
|
spl_autoload_unregister(array('ComposerAutoloaderInit99add140caccae6adfad678f070ccf26', 'loadClassLoader'));
|
||||||
|
|
||||||
require __DIR__ . '/autoload_static.php';
|
require __DIR__ . '/autoload_static.php';
|
||||||
call_user_func(\Composer\Autoload\ComposerStaticInitdf568b8a1948145d8f675fb08a939b09::getInitializer($loader));
|
call_user_func(\Composer\Autoload\ComposerStaticInit99add140caccae6adfad678f070ccf26::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 ComposerStaticInitdf568b8a1948145d8f675fb08a939b09
|
class ComposerStaticInit99add140caccae6adfad678f070ccf26
|
||||||
{
|
{
|
||||||
public static $prefixLengthsPsr4 = array (
|
public static $prefixLengthsPsr4 = array (
|
||||||
'C' =>
|
'C' =>
|
||||||
@@ -126,9 +126,9 @@ class ComposerStaticInitdf568b8a1948145d8f675fb08a939b09
|
|||||||
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 = ComposerStaticInitdf568b8a1948145d8f675fb08a939b09::$prefixLengthsPsr4;
|
$loader->prefixLengthsPsr4 = ComposerStaticInit99add140caccae6adfad678f070ccf26::$prefixLengthsPsr4;
|
||||||
$loader->prefixDirsPsr4 = ComposerStaticInitdf568b8a1948145d8f675fb08a939b09::$prefixDirsPsr4;
|
$loader->prefixDirsPsr4 = ComposerStaticInit99add140caccae6adfad678f070ccf26::$prefixDirsPsr4;
|
||||||
$loader->classMap = ComposerStaticInitdf568b8a1948145d8f675fb08a939b09::$classMap;
|
$loader->classMap = ComposerStaticInit99add140caccae6adfad678f070ccf26::$classMap;
|
||||||
|
|
||||||
}, null, ClassLoader::class);
|
}, null, ClassLoader::class);
|
||||||
}
|
}
|
||||||
|
14
vendor/composer/installed.json
vendored
14
vendor/composer/installed.json
vendored
@@ -151,17 +151,17 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "woocommerce/subscriptions-core",
|
"name": "woocommerce/subscriptions-core",
|
||||||
"version": "8.1.1",
|
"version": "8.2.0",
|
||||||
"version_normalized": "8.1.1.0",
|
"version_normalized": "8.2.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": "fb74303f96c53800aaec99a27e376aa9ece968cd"
|
"reference": "442d585955ab048673c765a8afca680b1ea38e07"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Automattic/woocommerce-subscriptions-core/zipball/fb74303f96c53800aaec99a27e376aa9ece968cd",
|
"url": "https://api.github.com/repos/Automattic/woocommerce-subscriptions-core/zipball/442d585955ab048673c765a8afca680b1ea38e07",
|
||||||
"reference": "fb74303f96c53800aaec99a27e376aa9ece968cd",
|
"reference": "442d585955ab048673c765a8afca680b1ea38e07",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -174,7 +174,7 @@
|
|||||||
"woocommerce/woocommerce-sniffs": "0.1.0",
|
"woocommerce/woocommerce-sniffs": "0.1.0",
|
||||||
"yoast/phpunit-polyfills": "1.1.0"
|
"yoast/phpunit-polyfills": "1.1.0"
|
||||||
},
|
},
|
||||||
"time": "2025-03-31T00:33:21+00:00",
|
"time": "2025-04-14T13:37:52+00:00",
|
||||||
"type": "wordpress-plugin",
|
"type": "wordpress-plugin",
|
||||||
"extra": {
|
"extra": {
|
||||||
"phpcodesniffer-search-depth": 2
|
"phpcodesniffer-search-depth": 2
|
||||||
@@ -204,7 +204,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/8.1.1",
|
"source": "https://github.com/Automattic/woocommerce-subscriptions-core/tree/8.2.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/7.3.1',
|
'pretty_version' => 'dev-release/7.4.0',
|
||||||
'version' => 'dev-release/7.3.1',
|
'version' => 'dev-release/7.4.0',
|
||||||
'reference' => 'bbd68f5de02c5b7fe412d87e548a957d7bfb8abf',
|
'reference' => 'f038fe29017b9110f7f39251b9c042a8c076125a',
|
||||||
'type' => 'wordpress-plugin',
|
'type' => 'wordpress-plugin',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -20,18 +20,18 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
'woocommerce/subscriptions-core' => array(
|
'woocommerce/subscriptions-core' => array(
|
||||||
'pretty_version' => '8.1.1',
|
'pretty_version' => '8.2.0',
|
||||||
'version' => '8.1.1.0',
|
'version' => '8.2.0.0',
|
||||||
'reference' => 'fb74303f96c53800aaec99a27e376aa9ece968cd',
|
'reference' => '442d585955ab048673c765a8afca680b1ea38e07',
|
||||||
'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/7.3.1',
|
'pretty_version' => 'dev-release/7.4.0',
|
||||||
'version' => 'dev-release/7.3.1',
|
'version' => 'dev-release/7.4.0',
|
||||||
'reference' => 'bbd68f5de02c5b7fe412d87e548a957d7bfb8abf',
|
'reference' => 'f038fe29017b9110f7f39251b9c042a8c076125a',
|
||||||
'type' => 'wordpress-plugin',
|
'type' => 'wordpress-plugin',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
|
@@ -430,9 +430,14 @@ a.close-subscriptions-search {
|
|||||||
max-width: 34%;
|
max-width: 34%;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
.variable_subscription_pricing_2_3.variable_subscription_trial p.form-row {
|
.variable_subscription_pricing_2_3.variable_subscription_pricing p.form-row {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
#variable_product_options
|
||||||
|
.variable_subscription_pricing_2_3
|
||||||
|
p._subscription_price_field {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
#variable_product_options
|
#variable_product_options
|
||||||
.variable_subscription_pricing_2_3
|
.variable_subscription_pricing_2_3
|
||||||
.wc_input_subscription_trial_period + .select2,
|
.wc_input_subscription_trial_period + .select2,
|
||||||
@@ -460,6 +465,11 @@ a.close-subscriptions-search {
|
|||||||
.wc_input_subscription_payment_sync_month {
|
.wc_input_subscription_payment_sync_month {
|
||||||
max-width: 86%;
|
max-width: 86%;
|
||||||
}
|
}
|
||||||
|
#variable_product_options
|
||||||
|
.variable_subscription_pricing_2_3 .multiple_fields .wrap {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
@media screen and ( max-width: 1190px ) {
|
@media screen and ( max-width: 1190px ) {
|
||||||
#variable_product_options
|
#variable_product_options
|
||||||
.variable_subscription_pricing_2_3
|
.variable_subscription_pricing_2_3
|
||||||
@@ -473,7 +483,6 @@ a.close-subscriptions-search {
|
|||||||
.variable_subscription_pricing_2_3
|
.variable_subscription_pricing_2_3
|
||||||
p._subscription_price_field {
|
p._subscription_price_field {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
}
|
||||||
#variable_product_options
|
#variable_product_options
|
||||||
.variable_subscription_pricing_2_3
|
.variable_subscription_pricing_2_3
|
||||||
@@ -922,3 +931,6 @@ table.form-table input#woocommerce_subscriptions_customer_notifications_offset {
|
|||||||
#wcs_order_price_lock > .woocommerce-help-tip {
|
#wcs_order_price_lock > .woocommerce-help-tip {
|
||||||
margin: 0 8px 0 2px;
|
margin: 0 8px 0 2px;
|
||||||
}
|
}
|
||||||
|
.show_if_subscription .select2-selection, .show_if_variable-subscription .select2-selection {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
@media only screen and ( max-width: 768px ) {
|
@media only screen and ( max-width: 768px ) {
|
||||||
.subscription_details .button {
|
.subscription_details .button {
|
||||||
|
box-sizing: border-box;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
padding-right: 0.5rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@@ -396,7 +396,7 @@ jQuery( function ( $ ) {
|
|||||||
// Add the subscription price fields above the standard price fields
|
// Add the subscription price fields above the standard price fields
|
||||||
$( this ).insertBefore( $regularPriceRow );
|
$( this ).insertBefore( $regularPriceRow );
|
||||||
|
|
||||||
$trialSignUpRow.insertBefore( $( this ) );
|
$trialSignUpRow.insertAfter( $( this ) );
|
||||||
|
|
||||||
// Replace the regular price field with the trial period field
|
// Replace the regular price field with the trial period field
|
||||||
$regularPriceRow
|
$regularPriceRow
|
||||||
|
@@ -1,7 +1,14 @@
|
|||||||
*** WooCommerce Subscriptions Core Changelog ***
|
*** WooCommerce Subscriptions Core Changelog ***
|
||||||
|
|
||||||
|
= 8.2.0 - 2025-04-14 =
|
||||||
|
* Update - Increase the number of args accepted by wcs_get_subscriptions(), to bring about parity with wc_get_orders().
|
||||||
|
* Dev - Update wcs_maybe_prefix_key() and wcs_maybe_unprefix_key() to support an array of keys.
|
||||||
|
* Fix - Prevent sending renewal reminders for orders with a 0 total.
|
||||||
|
* Fix - Ensure the second parameter passed to the 'get_edit_post_link' filter is an integer.
|
||||||
|
* Fix - Prevent WooCommerce Subscriptions buttons from overflowing in the View subscription page
|
||||||
|
|
||||||
= 8.1.1 - 2025-03-30 =
|
= 8.1.1 - 2025-03-30 =
|
||||||
* Update - Display the subscriptions parent order icon in the WooCommerce Orders list table by default.
|
* Update - Display the subscriptions parent order icon in the WooCommerce Orders list table by default
|
||||||
|
|
||||||
= 8.1.0 - 2025-03-24 =
|
= 8.1.0 - 2025-03-24 =
|
||||||
* Update - Improved subscription search performance for WP Post stores by removing unnecessary _order_key and _billing_email meta queries.
|
* Update - Improved subscription search performance for WP Post stores by removing unnecessary _order_key and _billing_email meta queries.
|
||||||
@@ -20,6 +27,7 @@
|
|||||||
* Fix - Prevent empty strings being saved in related orders cache ID meta when backfilling order data to the WP Posts table.
|
* Fix - Prevent empty strings being saved in related orders cache ID meta when backfilling order data to the WP Posts table.
|
||||||
* Fix - Correctly load product names with HTML on the cart and checkout shipping rates.
|
* Fix - Correctly load product names with HTML on the cart and checkout shipping rates.
|
||||||
* Dev - Fix Node version mismatch between package.json and .nvmrc (both are now set to v16.17.1).
|
* Dev - Fix Node version mismatch between package.json and .nvmrc (both are now set to v16.17.1).
|
||||||
|
* Add - Hooks to add more columns to the Related Orders table on admin
|
||||||
|
|
||||||
= 8.0.1 - 2025-02-13 =
|
= 8.0.1 - 2025-02-13 =
|
||||||
* Fix - Revert a change released in 7.2.0 which triggered the "woocommerce_cart_item_name" filter with the wrong number of parameters.
|
* Fix - Revert a change released in 7.2.0 which triggered the "woocommerce_cart_item_name" filter with the wrong number of parameters.
|
||||||
|
@@ -316,7 +316,8 @@ class WC_Subscriptions_Admin {
|
|||||||
?>
|
?>
|
||||||
</label>
|
</label>
|
||||||
<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 ) ); ?>" />
|
<?php // Translators: %s: formatted example price value. ?>
|
||||||
|
<input type="text" id="_subscription_price" name="_subscription_price" class="wc_input_price wc_input_subscription_price" placeholder="<?php echo esc_attr( sprintf( _x( 'e.g. %s', 'example price', 'woocommerce-subscriptions' ), wc_format_localized_price( '5.90' ) ) ); ?>" 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 wc-enhanced-select">
|
<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 ) { ?>
|
||||||
@@ -354,7 +355,8 @@ class WC_Subscriptions_Admin {
|
|||||||
'class' => 'wc_input_subscription_intial_price wc_input_subscription_initial_price wc_input_price short',
|
'class' => 'wc_input_subscription_intial_price wc_input_subscription_initial_price wc_input_price short',
|
||||||
// translators: %s is a currency symbol / code
|
// translators: %s is a currency symbol / code
|
||||||
'label' => sprintf( __( 'Sign-up fee (%s)', 'woocommerce-subscriptions' ), get_woocommerce_currency_symbol() ),
|
'label' => sprintf( __( 'Sign-up fee (%s)', 'woocommerce-subscriptions' ), get_woocommerce_currency_symbol() ),
|
||||||
'placeholder' => _x( 'e.g. 9.90', 'example price', 'woocommerce-subscriptions' ),
|
'placeholder' => // translators: %s the formatted example price value.
|
||||||
|
esc_attr( sprintf( _x( 'e.g. %s', 'example price', 'woocommerce-subscriptions' ), wc_format_localized_price( '5.90' ) ) ),
|
||||||
'description' => __( 'Optionally include an amount to be charged at the outset of the subscription. The sign-up fee will be charged immediately, even if the product has a free trial or the payment dates are synced.', 'woocommerce-subscriptions' ),
|
'description' => __( 'Optionally include an amount to be charged at the outset of the subscription. The sign-up fee will be charged immediately, even if the product has a free trial or the payment dates are synced.', 'woocommerce-subscriptions' ),
|
||||||
'desc_tip' => true,
|
'desc_tip' => true,
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
|
@@ -8,61 +8,79 @@
|
|||||||
if ( ! defined( 'ABSPATH' ) ) {
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
exit; // Exit if accessed directly
|
exit; // Exit if accessed directly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Order number column
|
||||||
|
// translators: placeholder is an order number.
|
||||||
|
$order_number = '<a href="' . esc_url( $order->get_edit_order_url() ) . '" aria-label="' . esc_attr( sprintf( __( 'Edit order number %s', 'woocommerce-subscriptions' ), $order->get_order_number() ) ) . '">' .
|
||||||
|
// translators: placeholder is an order number.
|
||||||
|
sprintf( esc_html_x( '#%s', 'hash before order number', 'woocommerce-subscriptions' ), esc_html( $order->get_order_number() ) ) .
|
||||||
|
'</a>';
|
||||||
|
|
||||||
|
// Relationship column
|
||||||
|
$relationship = esc_html( $order->get_meta( '_relationship' ) );
|
||||||
|
|
||||||
|
// Date created column
|
||||||
|
$date_created = $order->get_date_created();
|
||||||
|
|
||||||
|
if ( $date_created ) {
|
||||||
|
$t_time = $order->get_date_created()->date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
|
||||||
|
$date_to_display = ucfirst( wcs_get_human_time_diff( $date_created->getTimestamp() ) );
|
||||||
|
} else {
|
||||||
|
$t_time = __( 'Unpublished', 'woocommerce-subscriptions' );
|
||||||
|
$date_to_display = $t_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! wcs_is_custom_order_tables_usage_enabled() ) {
|
||||||
|
// Backwards compatibility for third-parties using the generic WP post time filter.
|
||||||
|
// Only apply this filter if HPOS is not enabled, as the filter is not compatible with HPOS.
|
||||||
|
$date_to_display = apply_filters( 'post_date_column_time', $date_to_display, get_post( $order->get_id() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$date_created = '<abbr title="' . esc_attr( $t_time ) . '">' . esc_html( apply_filters( 'wc_subscriptions_related_order_date_column', $date_to_display, $order ) ) . '</abbr>';
|
||||||
|
|
||||||
|
// Status column
|
||||||
|
$classes = array(
|
||||||
|
'order-status',
|
||||||
|
sanitize_html_class( 'status-' . $order->get_status() ),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( wcs_is_subscription( $order ) ) {
|
||||||
|
$status_name = wcs_get_subscription_status_name( $order->get_status() );
|
||||||
|
$classes[] = 'subscription-status';
|
||||||
|
} else {
|
||||||
|
$status_name = wc_get_order_status_name( $order->get_status() );
|
||||||
|
}
|
||||||
|
|
||||||
|
$status_html = '<mark class="' . esc_attr( implode( ' ', $classes ) ) . '"><span>' . esc_html( $status_name ) . '</span></mark>';
|
||||||
|
|
||||||
|
// Total column
|
||||||
|
$total = '<span class="amount">' . wp_kses(
|
||||||
|
$order->get_formatted_order_total(),
|
||||||
|
array(
|
||||||
|
'small' => array(),
|
||||||
|
'span' => array(
|
||||||
|
'class' => array(),
|
||||||
|
),
|
||||||
|
'del' => array(),
|
||||||
|
'ins' => array(),
|
||||||
|
)
|
||||||
|
) . '</span>';
|
||||||
|
|
||||||
|
$columns = array(
|
||||||
|
$order_number,
|
||||||
|
$relationship,
|
||||||
|
$date_created,
|
||||||
|
$status_html,
|
||||||
|
$total,
|
||||||
|
);
|
||||||
|
|
||||||
|
$columns = apply_filters( 'wcs_related_orders_table_row_columns', $columns );
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<?php foreach ( $columns as $column ) { ?>
|
||||||
<?php // translators: placeholder is an order number. ?>
|
<td>
|
||||||
<a href="<?php echo esc_url( $order->get_edit_order_url() ); ?>" aria-label="<?php echo esc_attr( sprintf( __( 'Edit order number %s', 'woocommerce-subscriptions' ), $order->get_order_number() ) ); ?>">
|
<?php echo wp_kses_post( $column ); ?>
|
||||||
<?php
|
</td>
|
||||||
// translators: placeholder is an order number.
|
<?php } ?>
|
||||||
echo sprintf( esc_html_x( '#%s', 'hash before order number', 'woocommerce-subscriptions' ), esc_html( $order->get_order_number() ) );
|
|
||||||
?>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<?php echo esc_html( $order->get_meta( '_relationship' ) ); ?>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<?php
|
|
||||||
$date_created = $order->get_date_created();
|
|
||||||
|
|
||||||
if ( $date_created ) {
|
|
||||||
$t_time = $order->get_date_created()->date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
|
|
||||||
$date_to_display = ucfirst( wcs_get_human_time_diff( $date_created->getTimestamp() ) );
|
|
||||||
} else {
|
|
||||||
$t_time = __( 'Unpublished', 'woocommerce-subscriptions' );
|
|
||||||
$date_to_display = $t_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! wcs_is_custom_order_tables_usage_enabled() ) {
|
|
||||||
// Backwards compatibility for third-parties using the generic WP post time filter.
|
|
||||||
// Only apply this filter if HPOS is not enabled, as the filter is not compatible with HPOS.
|
|
||||||
$date_to_display = apply_filters( 'post_date_column_time', $date_to_display, get_post( $order->get_id() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
<abbr title="<?php echo esc_attr( $t_time ); ?>">
|
|
||||||
<?php echo esc_html( apply_filters( 'wc_subscriptions_related_order_date_column', $date_to_display, $order ) ); ?>
|
|
||||||
</abbr>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<?php
|
|
||||||
$classes = array(
|
|
||||||
'order-status',
|
|
||||||
sanitize_html_class( 'status-' . $order->get_status() ),
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( wcs_is_subscription( $order ) ) {
|
|
||||||
$status_name = wcs_get_subscription_status_name( $order->get_status() );
|
|
||||||
$classes[] = 'subscription-status';
|
|
||||||
} else {
|
|
||||||
$status_name = wc_get_order_status_name( $order->get_status() );
|
|
||||||
}
|
|
||||||
|
|
||||||
printf( '<mark class="%s"><span>%s</span></mark>', esc_attr( implode( ' ', $classes ) ), esc_html( $status_name ) );
|
|
||||||
?>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span class="amount"><?php echo wp_kses( $order->get_formatted_order_total(), array( 'small' => array(), 'span' => array( 'class' => array() ), 'del' => array(), 'ins' => array() ) ); // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound ?></span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
@@ -10,16 +10,24 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
exit; // Exit if accessed directly
|
exit; // Exit if accessed directly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$columns = array(
|
||||||
|
esc_html__( 'Order Number', 'woocommerce-subscriptions' ),
|
||||||
|
esc_html__( 'Relationship', 'woocommerce-subscriptions' ),
|
||||||
|
esc_html__( 'Date', 'woocommerce-subscriptions' ),
|
||||||
|
esc_html__( 'Status', 'woocommerce-subscriptions' ),
|
||||||
|
esc_html_x( 'Total', 'table heading', 'woocommerce-subscriptions' ),
|
||||||
|
);
|
||||||
|
|
||||||
|
$columns = apply_filters( 'wcs_related_orders_table_header_columns', $columns );
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<div class="woocommerce_subscriptions_related_orders">
|
<div class="woocommerce_subscriptions_related_orders">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th><?php esc_html_e( 'Order Number', 'woocommerce-subscriptions' ); ?></th>
|
<?php foreach ( $columns as $row ) { ?>
|
||||||
<th><?php esc_html_e( 'Relationship', 'woocommerce-subscriptions' ); ?></th>
|
<th><?php echo wp_kses_post( $row ); ?></th>
|
||||||
<th><?php esc_html_e( 'Date', 'woocommerce-subscriptions' ); ?></th>
|
<?php } ?>
|
||||||
<th><?php esc_html_e( 'Status', 'woocommerce-subscriptions' ); ?></th>
|
|
||||||
<th><?php echo esc_html_x( 'Total', 'table heading', 'woocommerce-subscriptions' ); ?></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@@ -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 = '8.1.1'; // WRCS: DEFINED_VERSION.
|
protected $library_version = '8.2.0'; // WRCS: DEFINED_VERSION.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The subscription scheduler instance.
|
* The subscription scheduler instance.
|
||||||
|
@@ -156,6 +156,9 @@ class WC_Subscriptions_Email_Notifications {
|
|||||||
switch ( current_action() ) {
|
switch ( current_action() ) {
|
||||||
case 'woocommerce_scheduled_subscription_customer_notification_renewal':
|
case 'woocommerce_scheduled_subscription_customer_notification_renewal':
|
||||||
$subscription = wcs_get_subscription( $subscription_id );
|
$subscription = wcs_get_subscription( $subscription_id );
|
||||||
|
if ( $subscription->get_total() <= 0 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if ( $subscription->is_manual() ) {
|
if ( $subscription->is_manual() ) {
|
||||||
$notification = $emails['WCS_Email_Customer_Notification_Manual_Renewal'];
|
$notification = $emails['WCS_Email_Customer_Notification_Manual_Renewal'];
|
||||||
} else {
|
} else {
|
||||||
@@ -248,7 +251,7 @@ class WC_Subscriptions_Email_Notifications {
|
|||||||
$actions['wcs_customer_notification_subscription_expiration'] = esc_html__( 'Send upcoming subscription expiration notification', 'woocommerce-subscriptions' );
|
$actions['wcs_customer_notification_subscription_expiration'] = esc_html__( 'Send upcoming subscription expiration notification', 'woocommerce-subscriptions' );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( in_array( 'next_payment', $valid_notifications, true ) ) {
|
if ( in_array( 'next_payment', $valid_notifications, true ) && $theorder->get_total() > 0 ) {
|
||||||
$actions['wcs_customer_notification_renewal'] = esc_html__( 'Send upcoming renewal notification', 'woocommerce-subscriptions' );
|
$actions['wcs_customer_notification_renewal'] = esc_html__( 'Send upcoming renewal notification', 'woocommerce-subscriptions' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,19 +56,24 @@ function wcs_date_input( $timestamp = 0, $args = array() ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the edit post link without checking if the user can edit that post or not.
|
* Get the admin edit link for an order.
|
||||||
|
*
|
||||||
|
* Note: this function does not check if the user has permission to edit the order.
|
||||||
*
|
*
|
||||||
* @param int $post_id
|
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
|
||||||
|
* @since 7.4.0 - Added official support for WC_Order objects as the first parameter.
|
||||||
|
*
|
||||||
|
* @param int|WC_Order $order The order ID or WC_Order object.
|
||||||
|
* @return string The edit order URL or an empty string if the order is not found or is not a valid order type.
|
||||||
*/
|
*/
|
||||||
function wcs_get_edit_post_link( $post_id ) {
|
function wcs_get_edit_post_link( $order ) {
|
||||||
$object = wc_get_order( $post_id ); // works for both WC Order and WC Subscription objects.
|
$order = is_a( $order, 'WC_Abstract_Order' ) ? $order : wc_get_order( $order );
|
||||||
|
|
||||||
if ( ! $object || ! in_array( $object->get_type(), array( 'shop_order', 'shop_subscription' ), true ) ) {
|
if ( ! $order || ! in_array( $order->get_type(), array( 'shop_order', 'shop_subscription' ), true ) ) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return apply_filters( 'get_edit_post_link', $object->get_edit_order_url(), $post_id, '' );
|
return apply_filters( 'get_edit_post_link', $order->get_edit_order_url(), $order->get_id(), '' );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -162,26 +167,36 @@ function wcs_get_rounding_precision() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a prefix to a string if it doesn't already have it
|
* Add a prefix to a string or array of strings if it doesn't already have it
|
||||||
*
|
*
|
||||||
* @param string
|
* @param string|array $key The key or array of keys to add the prefix to.
|
||||||
* @param string
|
* @param string $prefix The prefix to add.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
* @return string
|
*
|
||||||
|
* @return string|array The key or array of keys with the prefix added.
|
||||||
*/
|
*/
|
||||||
function wcs_maybe_prefix_key( $key, $prefix = '_' ) {
|
function wcs_maybe_prefix_key( $key, $prefix = '_' ) {
|
||||||
return ( substr( $key, 0, strlen( $prefix ) ) != $prefix ) ? $prefix . $key : $key;
|
if ( is_array( $key ) ) {
|
||||||
|
return array_map( __FUNCTION__, $key, array_fill( 0, count( $key ), $prefix ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( substr( $key, 0, strlen( $prefix ) ) !== $prefix ) ? $prefix . $key : $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a prefix from a string if has it
|
* Remove a prefix from a string or array of strings if it has it.
|
||||||
*
|
*
|
||||||
* @param string $key
|
* @param string|array $key The key or array of keys to remove the prefix from.
|
||||||
* @param string $prefix
|
* @param string $prefix The prefix to remove.
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0
|
||||||
* @return string
|
*
|
||||||
|
* @return string|array The key or array of keys with the prefix removed.
|
||||||
*/
|
*/
|
||||||
function wcs_maybe_unprefix_key( $key, $prefix = '_' ) {
|
function wcs_maybe_unprefix_key( $key, $prefix = '_' ) {
|
||||||
|
if ( is_array( $key ) ) {
|
||||||
|
return array_map( __FUNCTION__, $key, array_fill( 0, count( $key ), $prefix ) );
|
||||||
|
}
|
||||||
|
|
||||||
return ( substr( $key, 0, strlen( $prefix ) ) === $prefix ) ? substr( $key, strlen( $prefix ) ) : $key;
|
return ( substr( $key, 0, strlen( $prefix ) ) === $prefix ) ? substr( $key, strlen( $prefix ) ) : $key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,53 +15,37 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<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">
|
|
||||||
<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' ); ?>">
|
|
||||||
</p>
|
|
||||||
<p class="form-row form-row-last show_if_variable-subscription">
|
|
||||||
<label for="variable_subscription_trial_length[<?php echo esc_attr( $loop ); ?>]">
|
|
||||||
<?php esc_html_e( 'Free trial', 'woocommerce-subscriptions' ); ?>
|
|
||||||
<?php // translators: placeholder is trial period validation message if passed an invalid value (e.g. "Trial period can not exceed 4 weeks") ?>
|
|
||||||
<?php echo wcs_help_tip( sprintf( _x( 'An optional period of time to wait before charging the first recurring payment. Any sign up fee will still be charged at the outset of the subscription. %s', 'Trial period dropdown\'s description in pricing fields', 'woocommerce-subscriptions' ), self::get_trial_period_validation_message() ) ); ?>
|
|
||||||
</label>
|
|
||||||
<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>
|
|
||||||
<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 ) : ?>
|
|
||||||
<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; ?>
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="variable_subscription_pricing variable_subscription_pricing_2_3 show_if_variable-subscription" style="display: none">
|
<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 multiple_fields 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
|
||||||
// translators: placeholder is a currency symbol / code
|
// translators: placeholder is a currency symbol / code
|
||||||
printf( esc_html__( 'Subscription price (%s)', 'woocommerce-subscriptions' ), esc_html( get_woocommerce_currency_symbol() ) );
|
printf( esc_html__( 'Subscription price (%s)', 'woocommerce-subscriptions' ), esc_html( get_woocommerce_currency_symbol() ) );
|
||||||
?>
|
?>
|
||||||
|
<?php echo wcs_help_tip( __( 'Choose the subscription price, billing interval and period.', 'woocommerce-subscriptions' ) ); ?>
|
||||||
</label>
|
</label>
|
||||||
<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>
|
<span class="wrap">
|
||||||
<select name="variable_subscription_period_interval[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_period_interval wc-enhanced-select">
|
<?php // Translators: %s: formatted example price value. ?>
|
||||||
<?php foreach ( wcs_get_subscription_period_interval_strings() as $key => $value ) : ?>
|
<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( sprintf( _x( 'e.g. %s', 'example price', 'woocommerce-subscriptions' ), esc_attr( wc_format_localized_price( '9.90' ) ) ) ); ?>">
|
||||||
<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; ?>
|
|
||||||
</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_interval[<?php echo esc_attr( $loop ); ?>]" class="wcs_hidden_label"><?php esc_html_e( 'Billing interval:', 'woocommerce-subscriptions' ); ?></label>
|
||||||
<select name="variable_subscription_period[<?php echo esc_attr( $loop ); ?>]" class="wc_input_subscription_period wc-enhanced-select">
|
<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_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, $billing_period ); ?>><?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>
|
||||||
|
<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 ) : ?>
|
||||||
|
<option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, $billing_period ); ?>><?php echo esc_html( $value ); ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
<p class="form-row form-row-last show_if_variable-subscription _subscription_length_field" style="display: none">
|
<p class="form-row form-row-last form-field 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( 'Stop renewing after', 'woocommerce-subscriptions' ); ?>
|
<?php esc_html_e( 'Stop renewing after', 'woocommerce-subscriptions' ); ?>
|
||||||
<?php echo wcs_help_tip( _x( 'Automatically stop renewing 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 stop renewing 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' ) ); ?>
|
||||||
@@ -73,3 +57,30 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<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">
|
||||||
|
<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() ) ); ?>
|
||||||
|
<?php echo wcs_help_tip( __( 'Optionally include an amount to be charged at the outset of the subscription. The sign-up fee will be charged immediately, even if the product has a free trial or the payment dates are synced.', 'woocommerce-subscriptions' ) ); ?>
|
||||||
|
</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.', 'example price', 'woocommerce-subscriptions' ); ?> <?php echo esc_attr( wc_format_localized_price( '9.90' ) ); ?>">
|
||||||
|
</p>
|
||||||
|
<p class="form-row multiple_fields form-field form-row-last show_if_variable-subscription">
|
||||||
|
<label for="variable_subscription_trial_length[<?php echo esc_attr( $loop ); ?>]">
|
||||||
|
<?php esc_html_e( 'Free trial', 'woocommerce-subscriptions' ); ?>
|
||||||
|
<?php // translators: placeholder is trial period validation message if passed an invalid value (e.g. "Trial period can not exceed 4 weeks") ?>
|
||||||
|
<?php echo wcs_help_tip( sprintf( _x( 'An optional period of time to wait before charging the first recurring payment. Any sign up fee will still be charged at the outset of the subscription. %s', 'Trial period dropdown\'s description in pricing fields', 'woocommerce-subscriptions' ), self::get_trial_period_validation_message() ) ); ?>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<span class="wrap">
|
||||||
|
<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>
|
||||||
|
<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 ) : ?>
|
||||||
|
<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; ?>
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
@@ -393,50 +393,58 @@ function wcs_sanitize_subscription_status_key( $status_key ) {
|
|||||||
/**
|
/**
|
||||||
* Gets a list of subscriptions that match a certain set of query arguments.
|
* Gets a list of subscriptions that match a certain set of query arguments.
|
||||||
*
|
*
|
||||||
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.
|
* @since 1.0.0 Migrated from WooCommerce Subscriptions v2.0.
|
||||||
|
* @since 7.3.0 Any additional arguments are passed across to WooCommerce for use in the final query.
|
||||||
*
|
*
|
||||||
* @param array $args {
|
* @param array $args {
|
||||||
* A set of name value pairs to query for subscriptions - similar to args supported by wc_get_orders().
|
* A set of name value pairs to query for subscriptions - similar to args supported by wc_get_orders().
|
||||||
|
* You can also provide other keys, such as but not limited to those supported by WooCommerce order queries.
|
||||||
*
|
*
|
||||||
* @type string $subscriptions_per_page The number of subscriptions to return. Set to -1 for unlimited. Default 10.
|
* @type int $subscriptions_per_page The number of subscriptions to return. Set to -1 for unlimited. Default 10.
|
||||||
* @type int $paged The page of subscriptions to return. Default 1.
|
* @type int $paged The page of subscriptions to return. Default 1.
|
||||||
* @type int $offset An optional number of subscription to displace or pass over. Default 0.
|
* @type int $offset An optional number of subscription to displace or pass over. Default 0.
|
||||||
* @type string $orderby The field which the subscriptions should be ordered by. Can be 'start_date', 'trial_end_date', 'end_date', 'status' or 'order_id'. Defaults to 'start_date'.
|
* @type string $orderby The field which the subscriptions should be ordered by. Can be 'start_date', 'trial_end_date', 'end_date', 'status' or 'order_id'. Defaults to 'start_date'.
|
||||||
* @type string $order The direction to order subscriptions by. Can be 'ASC' or 'DESC'. Defaults to 'DESC'.
|
* @type string $order The direction to order subscriptions by. Can be 'ASC' or 'DESC'. Defaults to 'DESC'.
|
||||||
* @type int $customer_id The ID of the customer whose subscriptions should be returned. Default 0 - No customer restriction.
|
* @type int $customer_id The ID of the customer whose subscriptions should be returned. Default 0 - No customer restriction.
|
||||||
* @type int $product_id To restrict subscriptions to those which contain a certain product ID. Default 0 - No product restriction.
|
* @type int $product_id To restrict subscriptions to those which contain a certain product ID. Default 0 - No product restriction.
|
||||||
* @type int $variation_id To restrict subscriptions to those which contain a certain product variation ID. Default 0 - No variation restriction.
|
* @type int $variation_id To restrict subscriptions to those which contain a certain product variation ID. Default 0 - No variation restriction.
|
||||||
* @type int $order_id To restrict subscriptions to those which have a certain parent order ID. Default 0 - No parent order restriction.
|
* @type int $order_id To restrict subscriptions to those which have a certain parent order ID. Default 0 - No parent order restriction.
|
||||||
* @type string $subscription_status The status of the subscriptions to return. Can be 'any', 'active', 'on-hold', 'pending', 'cancelled', 'expired', 'trash', 'pending-cancel'. Default 'any'.
|
* @type string|string[] $subscription_status The status of the subscriptions to return. Can be 'any', 'active', 'on-hold', 'pending', 'cancelled', 'expired', 'trash', 'pending-cancel'. Default 'any'.
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @return WC_Subscription[] An array of WC_Subscription objects keyed by their ID matching the query args.
|
* @return WC_Subscription[] An array of WC_Subscription objects keyed by their ID matching the query args.
|
||||||
*/
|
*/
|
||||||
function wcs_get_subscriptions( $args ) {
|
function wcs_get_subscriptions( $args ) {
|
||||||
$args = wp_parse_args(
|
$default_args = array(
|
||||||
$args,
|
'subscriptions_per_page' => 10,
|
||||||
array(
|
'paged' => 1,
|
||||||
'subscriptions_per_page' => 10,
|
'offset' => 0,
|
||||||
'paged' => 1,
|
'orderby' => 'start_date',
|
||||||
'offset' => 0,
|
'order' => 'DESC',
|
||||||
'orderby' => 'start_date',
|
'customer_id' => 0,
|
||||||
'order' => 'DESC',
|
'product_id' => 0,
|
||||||
'customer_id' => 0,
|
'variation_id' => 0,
|
||||||
'product_id' => 0,
|
'order_id' => 0,
|
||||||
'variation_id' => 0,
|
'subscription_status' => array( 'any' ),
|
||||||
'order_id' => 0,
|
'meta_query_relation' => 'AND',
|
||||||
'subscription_status' => array( 'any' ),
|
|
||||||
'meta_query_relation' => 'AND',
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$provided_args = wp_parse_args( $args );
|
||||||
|
$working_args = array_merge( $default_args, $provided_args );
|
||||||
|
$extra_args = array_diff_key( $provided_args, $default_args );
|
||||||
|
|
||||||
// If the order ID arg is not a shop_order then there's no need to proceed with the query.
|
// If the order ID arg is not a shop_order then there's no need to proceed with the query.
|
||||||
if ( 0 !== $args['order_id'] && 'shop_order' !== WC_Data_Store::load( 'order' )->get_order_type( $args['order_id'] ) ) {
|
if ( 0 !== $working_args['order_id'] && 'shop_order' !== WC_Data_Store::load( 'order' )->get_order_type( $working_args['order_id'] ) ) {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure subscription_status is an array.
|
// Support the direct use of 'status'.
|
||||||
$args['subscription_status'] = $args['subscription_status'] ? (array) $args['subscription_status'] : [];
|
if ( isset( $extra_args['status'] ) ) {
|
||||||
|
$working_args['subscription_status'] = $extra_args['status'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the status argument is an array.
|
||||||
|
$working_args['subscription_status'] = $working_args['subscription_status'] ? (array) $working_args['subscription_status'] : [];
|
||||||
|
|
||||||
// Grab the native post stati, removing pending and adding any.
|
// Grab the native post stati, removing pending and adding any.
|
||||||
$builtin = get_post_stati( [ '_builtin' => true ] );
|
$builtin = get_post_stati( [ '_builtin' => true ] );
|
||||||
@@ -444,7 +452,7 @@ function wcs_get_subscriptions( $args ) {
|
|||||||
$builtin['any'] = 'any';
|
$builtin['any'] = 'any';
|
||||||
|
|
||||||
// Make sure statuses start with 'wc-'.
|
// Make sure statuses start with 'wc-'.
|
||||||
foreach ( $args['subscription_status'] as &$status ) {
|
foreach ( $working_args['subscription_status'] as &$status ) {
|
||||||
if ( isset( $builtin[ $status ] ) ) {
|
if ( isset( $builtin[ $status ] ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -455,23 +463,25 @@ function wcs_get_subscriptions( $args ) {
|
|||||||
// Prepare the args for WC_Order_Query.
|
// Prepare the args for WC_Order_Query.
|
||||||
$query_args = array(
|
$query_args = array(
|
||||||
'type' => 'shop_subscription',
|
'type' => 'shop_subscription',
|
||||||
'status' => $args['subscription_status'],
|
'status' => $working_args['subscription_status'],
|
||||||
'limit' => $args['subscriptions_per_page'],
|
'limit' => $working_args['limit'] ?? $working_args['subscriptions_per_page'],
|
||||||
'page' => $args['paged'],
|
'offset' => $working_args['offset'] > 0 ? $working_args['offset'] : null,
|
||||||
'offset' => $args['offset'] > 0 ? $args['offset'] : null,
|
'order' => $working_args['order'],
|
||||||
'order' => $args['order'],
|
|
||||||
'return' => 'ids',
|
'return' => 'ids',
|
||||||
// just in case we need to filter or order by meta values later
|
// just in case we need to filter or order by meta values later
|
||||||
'meta_query' => isset( $args['meta_query'] ) ? $args['meta_query'] : array(), // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
'meta_query' => isset( $working_args['meta_query'] ) ? $working_args['meta_query'] : array(), // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Remove Subscriptions-specific args which exist as aliases of regular order query args.
|
||||||
|
unset( $query_args['subscription_status'], $query_args['subscriptions_per_page'] );
|
||||||
|
|
||||||
// Maybe only get subscriptions created by a certain order
|
// Maybe only get subscriptions created by a certain order
|
||||||
if ( 0 !== $args['order_id'] && is_numeric( $args['order_id'] ) ) {
|
if ( 0 !== $working_args['order_id'] && is_numeric( $working_args['order_id'] ) ) {
|
||||||
$query_args['parent'] = $args['order_id'];
|
$query_args['parent'] = $working_args['order_id'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map subscription specific orderby values to internal keys.
|
// Map subscription specific orderby values to internal keys.
|
||||||
switch ( $args['orderby'] ) {
|
switch ( $working_args['orderby'] ) {
|
||||||
case 'status':
|
case 'status':
|
||||||
wcs_deprecated_argument( __FUNCTION__, 'subscriptions-core 5.0.0', 'The "status" orderby value is deprecated.' );
|
wcs_deprecated_argument( __FUNCTION__, 'subscriptions-core 5.0.0', 'The "status" orderby value is deprecated.' );
|
||||||
break;
|
break;
|
||||||
@@ -481,8 +491,8 @@ function wcs_get_subscriptions( $args ) {
|
|||||||
case 'trial_end_date':
|
case 'trial_end_date':
|
||||||
case 'end_date':
|
case 'end_date':
|
||||||
// We need to orderby post meta value: http://www.paulund.co.uk/order-meta-query
|
// We need to orderby post meta value: http://www.paulund.co.uk/order-meta-query
|
||||||
$date_type = str_replace( '_date', '', $args['orderby'] );
|
$date_type = str_replace( '_date', '', $working_args['orderby'] );
|
||||||
$query_args = array_merge( $query_args, array(
|
$query_args = array_merge( $query_args, array(
|
||||||
'orderby' => 'meta_value',
|
'orderby' => 'meta_value',
|
||||||
'meta_key' => wcs_get_date_meta_key( $date_type ),
|
'meta_key' => wcs_get_date_meta_key( $date_type ),
|
||||||
'meta_type' => 'DATETIME',
|
'meta_type' => 'DATETIME',
|
||||||
@@ -494,51 +504,56 @@ function wcs_get_subscriptions( $args ) {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$query_args['orderby'] = $args['orderby'];
|
$query_args['orderby'] = $working_args['orderby'];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maybe filter to a specific customer.
|
// Maybe filter to a specific customer.
|
||||||
if ( 0 !== $args['customer_id'] && is_numeric( $args['customer_id'] ) ) {
|
if ( 0 !== $working_args['customer_id'] && is_numeric( $working_args['customer_id'] ) ) {
|
||||||
// When HPOS is disabled, fetch subscriptions by customer_id using the user's subscription cache and query by post__in for improved performance.
|
// When HPOS is disabled, fetch subscriptions by customer_id using the user's subscription cache and query by post__in for improved performance.
|
||||||
if ( ! wcs_is_custom_order_tables_usage_enabled() ) {
|
if ( ! wcs_is_custom_order_tables_usage_enabled() ) {
|
||||||
$users_subscription_ids = WCS_Customer_Store::instance()->get_users_subscription_ids( $args['customer_id'] );
|
$users_subscription_ids = WCS_Customer_Store::instance()->get_users_subscription_ids( $working_args['customer_id'] );
|
||||||
$query_args = WCS_Admin_Post_Types::set_post__in_query_var( $query_args, $users_subscription_ids );
|
$query_args = WCS_Admin_Post_Types::set_post__in_query_var( $query_args, $users_subscription_ids );
|
||||||
} else {
|
} else {
|
||||||
$query_args['customer_id'] = $args['customer_id'];
|
$query_args['customer_id'] = $working_args['customer_id'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's more efficient to filter the results by product ID or variation ID rather than querying for via a "post__in" clause.
|
// It's more efficient to filter the results by product ID or variation ID rather than querying for via a "post__in" clause.
|
||||||
// This can only work where we know that the results will be sufficiently limited by the other query args. ie when we're querying by customer_id or order_id.
|
// This can only work where we know that the results will be sufficiently limited by the other query args. ie when we're querying by customer_id or order_id.
|
||||||
// We store the filters in a separate array so that we can apply them after the query has been run.
|
// We store the filters in a separate array so that we can apply them after the query has been run.
|
||||||
$query_controller = new WC_Subscription_Query_Controller( $args );
|
$query_controller = new WC_Subscription_Query_Controller( $working_args );
|
||||||
|
|
||||||
// We need to restrict subscriptions to those which contain a certain product/variation.
|
// We need to restrict subscriptions to those which contain a certain product/variation.
|
||||||
if ( $query_controller->has_product_query() ) {
|
if ( $query_controller->has_product_query() ) {
|
||||||
if ( $query_controller->should_filter_query_results() ) {
|
if ( $query_controller->should_filter_query_results() ) {
|
||||||
// We will filter the results and apply any paging, limit and offset after the query has been run.
|
// We will filter the results and apply any paging, limit and offset after the query has been run.
|
||||||
unset( $args['product_id'], $args['variation_id'], $query_args['limit'], $query_args['paged'], $query_args['offset'] );
|
unset( $working_args['product_id'], $working_args['variation_id'], $query_args['limit'], $query_args['paged'], $query_args['offset'] );
|
||||||
|
|
||||||
// We need to get all subscriptions otherwise the limit could be filled with subscriptions that don't contain the product.
|
// We need to get all subscriptions otherwise the limit could be filled with subscriptions that don't contain the product.
|
||||||
$query_args['limit'] = -1;
|
$query_args['limit'] = -1;
|
||||||
} else {
|
} else {
|
||||||
$subscriptions_for_product = wcs_get_subscriptions_for_product( array( $args['product_id'], $args['variation_id'] ) );
|
$subscriptions_for_product = wcs_get_subscriptions_for_product( array( $working_args['product_id'], $working_args['variation_id'] ) );
|
||||||
$query_args = WCS_Admin_Post_Types::set_post__in_query_var( $query_args, $subscriptions_for_product );
|
$query_args = WCS_Admin_Post_Types::set_post__in_query_var( $query_args, $subscriptions_for_product );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty( $query_args['meta_query'] ) ) {
|
if ( ! empty( $query_args['meta_query'] ) ) {
|
||||||
$query_args['meta_query']['relation'] = $args['meta_query_relation'];
|
$query_args['meta_query']['relation'] = $working_args['meta_query_relation'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We add any extra args, that are not specific to Subscriptions-queries, to the final set of query args.
|
||||||
|
// Merge order is important to prevent callers from overriding fields such as 'type', or where they might
|
||||||
|
// interfere with clever things we are doing re pagination.
|
||||||
|
$query_args = array_merge( $extra_args, $query_args );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters the query arguments used to retrieve subscriptions in wcs_get_subscriptions().
|
* Filters the query arguments used to retrieve subscriptions in wcs_get_subscriptions().
|
||||||
*
|
*
|
||||||
* @param array $query_args The query arguments used to retrieve subscriptions.
|
* @param array $query_args The query arguments used to retrieve subscriptions.
|
||||||
* @param array $args The original wcs_get_subscription() $args parameter.
|
* @param array $working_args The original wcs_get_subscription() $args parameter.
|
||||||
*/
|
*/
|
||||||
$query_args = apply_filters( 'woocommerce_get_subscriptions_query_args', $query_args, $args );
|
$query_args = apply_filters( 'woocommerce_get_subscriptions_query_args', $query_args, $working_args );
|
||||||
$subscriptions = array();
|
$subscriptions = array();
|
||||||
|
|
||||||
foreach ( wcs_get_orders_with_meta_query( $query_args ) as $subscription_id ) {
|
foreach ( wcs_get_orders_with_meta_query( $query_args ) as $subscription_id ) {
|
||||||
@@ -551,7 +566,7 @@ function wcs_get_subscriptions( $args ) {
|
|||||||
$subscriptions = $query_controller->paginate_results( $subscriptions );
|
$subscriptions = $query_controller->paginate_results( $subscriptions );
|
||||||
}
|
}
|
||||||
|
|
||||||
return apply_filters( 'woocommerce_got_subscriptions', $subscriptions, $args );
|
return apply_filters( 'woocommerce_got_subscriptions', $subscriptions, $working_args );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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: 8.1.1
|
* Version: 8.2.0
|
||||||
*/
|
*/
|
||||||
|
@@ -5,7 +5,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.
|
||||||
* Author: WooCommerce
|
* Author: WooCommerce
|
||||||
* Author URI: https://woocommerce.com/
|
* Author URI: https://woocommerce.com/
|
||||||
* Version: 7.3.1
|
* Version: 7.4.0
|
||||||
* Requires Plugins: woocommerce
|
* Requires Plugins: woocommerce
|
||||||
*
|
*
|
||||||
* WC requires at least: 8.7.1
|
* WC requires at least: 8.7.1
|
||||||
@@ -78,7 +78,7 @@ class WC_Subscriptions {
|
|||||||
public static $plugin_file = __FILE__;
|
public static $plugin_file = __FILE__;
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
public static $version = '7.3.1'; // WRCS: DEFINED_VERSION.
|
public static $version = '7.4.0'; // WRCS: DEFINED_VERSION.
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
public static $wc_minimum_supported_version = '7.7';
|
public static $wc_minimum_supported_version = '7.7';
|
||||||
@@ -149,7 +149,7 @@ class WC_Subscriptions {
|
|||||||
$trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 1 );
|
$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.Security.EscapeOutput.OutputNotEscaped
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user