Merge branch 'release/2.3.5'
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 885 B After Width: | Height: | Size: 885 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 250 KiB After Width: | Height: | Size: 250 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
|
@ -1,5 +1,15 @@
|
|||
*** WooCommerce Subscriptions Changelog ***
|
||||
|
||||
2018.08.27 - version 2.3.5
|
||||
* Fix: Exclude customers with at least 1 subscription from the WC inactivity user cleanup query. PR#2830
|
||||
* Fix: Calculate PayPal trial args from the next payment date while resubscribing before the subscription's end date. PR#2828
|
||||
* Fix: Only display the 2.3 upgrade notice after plugin upgrade, not after install. PR#2869
|
||||
* Tweak: Add 'woocommerce_subscriptions_can_user_renew_early' filter to allow third-parties to filter renew early eligibility. PR#2859
|
||||
* Tweak: Include resubscribe data in the subscription REST API response. PR#2863
|
||||
* Tweak: Improve the performance of some queries by using cached customer subscriptions instead of meta queries. PR#2856
|
||||
* Tweak: Improve the performance of the query which generates the data for the Subscriptions by Date report. PR#2788
|
||||
* Tweak: Give customers the option to update their subscription tokens after changing their default method. PR#2819
|
||||
|
||||
2018.08.10 - version 2.3.4
|
||||
* New: Add filter to bypass coupon removal for recurring carts. PR#2832
|
||||
* Fix: Check if subscription is payable before populating the cart with a renewal order. PR#2838
|
||||
|
|
|
|||
|
|
@ -23,6 +23,19 @@ if ( class_exists( 'WCS_Admin_Post_Types' ) ) {
|
|||
*/
|
||||
class WCS_Admin_Post_Types {
|
||||
|
||||
/**
|
||||
* The value to use for the 'post__in' query param when no results should be returned.
|
||||
*
|
||||
* We can't use an empty array, because WP returns all posts when post__in is an empty
|
||||
* array. Source: https://core.trac.wordpress.org/ticket/28099
|
||||
*
|
||||
* This would ideally be a private CONST but visibility modifiers are only allowed for
|
||||
* class constants in PHP >= 7.1.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $post__in_none = array( 0 );
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
|
@ -732,24 +745,20 @@ class WCS_Admin_Post_Types {
|
|||
if ( 'shop_subscription' === $typenow ) {
|
||||
|
||||
// Filter the orders by the posted customer.
|
||||
if ( isset( $_GET['_customer_user'] ) && $_GET['_customer_user'] > 0 ) {
|
||||
$vars['meta_query'][] = array(
|
||||
'key' => '_customer_user',
|
||||
'value' => (int) $_GET['_customer_user'],
|
||||
'compare' => '=',
|
||||
);
|
||||
if ( isset( $_GET['_subscriber_id'] ) && $_GET['_subscriber_id'] > 0 ) {
|
||||
$subscription_ids = WCS_Customer_Store::instance()->get_users_subscription_ids( absint( $_GET['_subscriber_id'] ) );
|
||||
$vars = self::set_post__in_query_var( $vars, $subscription_ids );
|
||||
}
|
||||
|
||||
if ( isset( $_GET['_wcs_product'] ) && $_GET['_wcs_product'] > 0 ) {
|
||||
|
||||
$subscription_ids = wcs_get_subscriptions_for_product( $_GET['_wcs_product'] );
|
||||
$subscription_ids = array_keys( $subscription_ids );
|
||||
$vars = self::set_post__in_query_var( $vars, $subscription_ids );
|
||||
}
|
||||
|
||||
if ( ! empty( $subscription_ids ) ) {
|
||||
$vars['post__in'] = $subscription_ids;
|
||||
} else {
|
||||
// no subscriptions contain this product, but we need to pass post__in an ID that no post will have because WP returns all posts when post__in is an empty array: https://core.trac.wordpress.org/ticket/28099
|
||||
$vars['post__in'] = array( 0 );
|
||||
}
|
||||
// If we've using the 'none' flag for the post__in query var, there's no need to apply other query filters, as we're going to return no subscriptions anyway
|
||||
if ( isset( $vars['post__in'] ) && self::$post__in_none === $vars['post__in'] ) {
|
||||
return $vars;
|
||||
}
|
||||
|
||||
if ( ! empty( $_GET['_payment_method'] ) ) {
|
||||
|
|
@ -779,7 +788,7 @@ class WCS_Admin_Post_Types {
|
|||
if ( ! empty( $subscription_ids ) ) {
|
||||
$vars['post__in'] = $subscription_ids;
|
||||
} else {
|
||||
$vars['post__in'] = array( 0 );
|
||||
$vars['post__in'] = self::$post__in_none;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -816,6 +825,40 @@ class WCS_Admin_Post_Types {
|
|||
return $vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'post__in' query var with a given set of post ids.
|
||||
*
|
||||
* There are a few special conditions for handling the post__in value. Namely:
|
||||
* - if there are no matching post_ids, the value should be array( 0 ), not an empty array()
|
||||
* - if there are existing IDs in post__in, we only want to retun posts with an ID in both
|
||||
* the existing set and the new set
|
||||
*
|
||||
* While this method is public, it should not be used as it will eventually be deprecated and
|
||||
* it's only made publicly available for other Subscriptions methods until Subscriptions
|
||||
* requires WC 3.0, and can rely on using methods in the data store rather than a hack like
|
||||
* pulling this for use outside of the admin context.
|
||||
*
|
||||
* @param array $query_vars
|
||||
* @param array $post_ids
|
||||
* @return array
|
||||
*/
|
||||
public static function set_post__in_query_var( $query_vars, $post_ids ) {
|
||||
|
||||
if ( empty( $post_ids ) ) {
|
||||
// No posts for this user
|
||||
$query_vars['post__in'] = self::$post__in_none;
|
||||
} elseif ( ! isset( $query_vars['post__in'] ) ) {
|
||||
// No other posts limitations, include all of these posts
|
||||
$query_vars['post__in'] = $post_ids;
|
||||
} elseif ( self::$post__in_none !== $query_vars['post__in'] ) {
|
||||
// Existing post limitation, we only want to include existing IDs that are also in this new set of IDs
|
||||
$intersecting_post_ids = array_intersect( $query_vars['post__in'], $post_ids );
|
||||
$query_vars['post__in'] = empty( $intersecting_post_ids ) ? self::$post__in_none : $intersecting_post_ids;
|
||||
}
|
||||
|
||||
return $query_vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change messages when a post type is updated.
|
||||
*
|
||||
|
|
@ -1062,8 +1105,8 @@ class WCS_Admin_Post_Types {
|
|||
$user_string = '';
|
||||
$user_id = '';
|
||||
|
||||
if ( ! empty( $_GET['_customer_user'] ) ) {
|
||||
$user_id = absint( $_GET['_customer_user'] );
|
||||
if ( ! empty( $_GET['_subscriber_id'] ) ) {
|
||||
$user_id = absint( $_GET['_subscriber_id'] );
|
||||
$user = get_user_by( 'id', $user_id );
|
||||
|
||||
$user_string = sprintf(
|
||||
|
|
@ -1075,7 +1118,7 @@ class WCS_Admin_Post_Types {
|
|||
);
|
||||
}
|
||||
?>
|
||||
<select class="wc-customer-search" name="_customer_user" data-placeholder="<?php esc_attr_e( 'Search for a customer…', 'woocommerce-subscriptions' ); ?>" data-allow_clear="true">
|
||||
<select class="wc-customer-search" name="_subscriber_id" data-placeholder="<?php esc_attr_e( 'Search for a customer…', 'woocommerce-subscriptions' ); ?>" data-allow_clear="true">
|
||||
<option value="<?php echo esc_attr( $user_id ); ?>" selected="selected"><?php echo wp_kses_post( $user_string ); ?></option>
|
||||
</select>
|
||||
<?php
|
||||
|
|
|
|||
0
includes/admin/debug-tools/class-wcs-debug-tool-cache-background-updater.php
Normal file → Executable file
0
includes/admin/meta-boxes/class-wcs-meta-box-subscription-schedule.php
Normal file → Executable file
0
includes/admin/reports/class-wcs-report-subscription-by-customer.php
Normal file → Executable file
48
includes/admin/reports/class-wcs-report-subscription-events-by-date.php
Normal file → Executable file
|
|
@ -257,47 +257,45 @@ class WC_Report_Subscription_Events_By_Date extends WC_Admin_Report {
|
|||
$query = $wpdb->prepare(
|
||||
"SELECT searchdate.Date as date, COUNT( DISTINCT wcsubs.ID) as count
|
||||
FROM (
|
||||
SELECT DATE_FORMAT(a.Date,'%%Y-%%m-%%d') as Date, 0 as cnt
|
||||
SELECT DATE_FORMAT(last_thousand_days.Date,'%%Y-%%m-%%d') as Date
|
||||
FROM (
|
||||
SELECT DATE(%s) - INTERVAL(a.a + (10 * b.a) + (100 * c.a)) DAY as Date
|
||||
SELECT DATE(%s) - INTERVAL(units.digit + (10 * tens.digit) + (100 * hundreds.digit)) DAY as Date
|
||||
FROM (
|
||||
SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2
|
||||
SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2
|
||||
UNION ALL SELECT 3 UNION ALL SELECT 4
|
||||
UNION ALL SELECT 5 UNION ALL SELECT 6
|
||||
UNION ALL SELECT 7 UNION ALL SELECT 8
|
||||
UNION ALL SELECT 9
|
||||
) as a
|
||||
) as units
|
||||
CROSS JOIN (
|
||||
SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2
|
||||
SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2
|
||||
UNION ALL SELECT 3 UNION ALL SELECT 4
|
||||
UNION ALL SELECT 5 UNION ALL SELECT 6
|
||||
UNION ALL SELECT 7 UNION ALL SELECT 8
|
||||
UNION ALL SELECT 9
|
||||
) as b
|
||||
) as tens
|
||||
CROSS JOIN (
|
||||
SELECT 0 AS a UNION ALL SELECT 1 UNION ALL SELECT 2
|
||||
SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2
|
||||
UNION ALL SELECT 3 UNION ALL SELECT 4
|
||||
UNION ALL SELECT 5 UNION ALL SELECT 6
|
||||
UNION ALL SELECT 7 UNION ALL SELECT 8
|
||||
UNION ALL SELECT 9
|
||||
) AS c
|
||||
) a
|
||||
WHERE a.Date >= %s AND a.Date <= %s
|
||||
) searchdate
|
||||
LEFT JOIN (
|
||||
{$wpdb->posts} AS wcsubs
|
||||
LEFT JOIN {$wpdb->postmeta} AS wcsmeta
|
||||
ON wcsubs.ID = wcsmeta.post_id AND wcsmeta.meta_key = %s
|
||||
) ON DATE( wcsubs.post_date ) < searchdate.Date
|
||||
AND wcsubs.post_type IN ( 'shop_subscription' )
|
||||
AND wcsubs.post_status NOT IN( 'trash', 'auto-draft' )
|
||||
AND (
|
||||
DATE( CONVERT_TZ( wcsmeta.meta_value , '+00:00', %s ) ) >= searchdate.Date
|
||||
OR wcsmeta.meta_value = 0
|
||||
OR wcsmeta.meta_value IS NULL
|
||||
)
|
||||
GROUP BY searchdate.Date
|
||||
ORDER BY searchdate.Date ASC",
|
||||
) AS hundreds
|
||||
) last_thousand_days
|
||||
WHERE last_thousand_days.Date >= %s AND last_thousand_days.Date <= %s
|
||||
) searchdate,
|
||||
{$wpdb->posts} AS wcsubs,
|
||||
{$wpdb->postmeta} AS wcsmeta
|
||||
WHERE wcsubs.ID = wcsmeta.post_id AND wcsmeta.meta_key = '%s'
|
||||
AND DATE( wcsubs.post_date ) <= searchdate.Date
|
||||
AND wcsubs.post_type IN ( 'shop_subscription' )
|
||||
AND wcsubs.post_status NOT IN( 'auto-draft' )
|
||||
AND (
|
||||
DATE( CONVERT_TZ( wcsmeta.meta_value , '+00:00', %s ) ) >= searchdate.Date
|
||||
OR wcsmeta.meta_value = 0
|
||||
OR wcsmeta.meta_value IS NULL
|
||||
)
|
||||
ORDER BY searchdate.Date ASC",
|
||||
$query_end_date,
|
||||
date( 'Y-m-d', $this->start_date ),
|
||||
$query_end_date,
|
||||
|
|
|
|||
0
includes/admin/reports/class-wcs-report-subscription-payment-retry.php
Normal file → Executable file
0
includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php
Normal file → Executable file
|
|
@ -81,8 +81,13 @@ class WC_REST_Subscriptions_Controller extends WC_REST_Orders_V1_Controller {
|
|||
if ( ! empty( $post->post_type ) && ! empty( $post->ID ) && 'shop_subscription' == $post->post_type ) {
|
||||
$subscription = wcs_get_subscription( $post->ID );
|
||||
|
||||
$response->data['billing_period'] = $subscription->get_billing_period();
|
||||
$response->data['billing_interval'] = $subscription->get_billing_interval();
|
||||
$response->data['billing_period'] = $subscription->get_billing_period();
|
||||
$response->data['billing_interval'] = $subscription->get_billing_interval();
|
||||
|
||||
// Send resubscribe data
|
||||
$resubscribed_subscriptions = array_filter( $subscription->get_related_orders( 'ids', 'resubscribe' ), 'wcs_is_subscription' );
|
||||
$response->data['resubscribed_from'] = strval( wcs_get_objects_property( $subscription, 'subscription_resubscribe' ) );
|
||||
$response->data['resubscribed_subscription'] = strval( reset( $resubscribed_subscriptions ) ); // Subscriptions can only be resubscribed to once so return the first and only element.
|
||||
|
||||
foreach ( array( 'start', 'trial_end', 'next_payment', 'end' ) as $date_type ) {
|
||||
$date_type_key = ( 'start' === $date_type ) ? 'date_created' : $date_type;
|
||||
|
|
@ -447,6 +452,18 @@ class WC_REST_Subscriptions_Controller extends WC_REST_Orders_V1_Controller {
|
|||
'type' => 'date-time',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'resubscribed_from' => array(
|
||||
'description' => __( "The subscription's original subscription ID if this is a resubscribed subscription.", 'woocommerce-subscriptions' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
'resubscribed_subscription' => array(
|
||||
'description' => __( "The subscription's resubscribed subscription ID.", 'woocommerce-subscriptions' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
);
|
||||
|
||||
$schema['properties'] += $subscriptions_schema;
|
||||
|
|
|
|||