diff --git a/changelog.txt b/changelog.txt index f0d9de7..a0b80bf 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,13 @@ *** 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 * Update: Display the subscription parent order icon in the WooCommerce Orders list table by default. * Dev: Update subscriptions-core to 8.1.1 diff --git a/includes/admin/reports/class-wcs-report-dashboard.php b/includes/admin/reports/class-wcs-report-dashboard.php index 211143d..4771f87 100644 --- a/includes/admin/reports/class-wcs-report-dashboard.php +++ b/includes/admin/reports/class-wcs-report-dashboard.php @@ -66,8 +66,8 @@ class WCS_Report_Dashboard { WHERE wcorder.post_type IN ( 'shop_order' ) AND wcsubs.post_type IN ( 'shop_subscription' ) 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-d', strtotime( '+1 DAY', current_time( 'timestamp' ) ) ) ); @@ -76,6 +76,7 @@ class WCS_Report_Dashboard { if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { $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 ) ); $update_cache = true; } @@ -95,8 +96,8 @@ class WCS_Report_Dashboard { WHERE wcorder.post_type IN ( 'shop_order' ) AND wcsubs.post_type IN ( 'shop_subscription' ) 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 WHERE order_total_meta.meta_key = '_order_total'", 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 ] ) ) { $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 ) ); $update_cache = true; } @@ -125,8 +127,8 @@ class WCS_Report_Dashboard { ) WHERE wcorder.post_type IN ( 'shop_order' ) 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-d', strtotime( '+1 DAY', current_time( 'timestamp' ) ) ) ); @@ -135,6 +137,7 @@ class WCS_Report_Dashboard { if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { $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 ) ); $update_cache = true; } @@ -157,8 +160,8 @@ class WCS_Report_Dashboard { ) WHERE wcorder.post_type IN ( 'shop_order' ) 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 WHERE order_total_meta.meta_key = '_order_total'", date( 'Y-m-01', current_time( 'timestamp' ) ), @@ -169,6 +172,7 @@ class WCS_Report_Dashboard { if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { $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 ) ); $update_cache = true; } @@ -183,7 +187,8 @@ class WCS_Report_Dashboard { ON wcsubs.ID = wcsmeta_cancel.post_id AND wcsmeta_cancel.meta_key = '_schedule_cancelled' 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-d', strtotime( '+1 DAY', current_time( 'timestamp' ) ) ) ); @@ -192,6 +197,7 @@ class WCS_Report_Dashboard { if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { $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 ) ); $update_cache = true; } diff --git a/includes/admin/reports/class-wcs-report-retention-rate.php b/includes/admin/reports/class-wcs-report-retention-rate.php index 26418cf..a1674b3 100644 --- a/includes/admin/reports/class-wcs-report-retention-rate.php +++ b/includes/admin/reports/class-wcs-report-retention-rate.php @@ -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 ); // 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( - "SELECT - 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, - COUNT(posts.ID) as count - FROM {$wpdb->prefix}posts posts - LEFT JOIN {$wpdb->prefix}postmeta cancelled_date - ON posts.ID = cancelled_date.post_id - AND cancelled_date.meta_key = %s - AND cancelled_date.meta_value <> '0' - LEFT JOIN {$wpdb->prefix}postmeta end_date - ON posts.ID = end_date.post_id - AND end_date.meta_key = %s - WHERE posts.post_type = 'shop_subscription' - AND posts.post_status NOT IN( 'wc-pending', 'trash' ) - GROUP BY periods_active - ORDER BY periods_active ASC", - $days_in_interval_period, - ( $oldest_subscription_age + 1 ), // Consider living subscriptions as being alive for one period longer than the longest living subsription - 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 subscritions that have expired + $subscription_ages = $wpdb->get_results( + $wpdb->prepare( + "SELECT + 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, + COUNT(posts.ID) as count + FROM {$wpdb->prefix}posts posts + LEFT JOIN {$wpdb->prefix}postmeta cancelled_date + ON posts.ID = cancelled_date.post_id + AND cancelled_date.meta_key = %s + AND cancelled_date.meta_value <> '0' + LEFT JOIN {$wpdb->prefix}postmeta end_date + ON posts.ID = end_date.post_id + AND end_date.meta_key = %s + WHERE posts.post_type = 'shop_subscription' + AND posts.post_status NOT IN( 'wc-pending', 'trash' ) + GROUP BY periods_active + ORDER BY periods_active ASC", + $days_in_interval_period, + ( $oldest_subscription_age + 1 ), // Consider living subscriptions as being alive for one period longer than the longest living subscription + 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->living_subscriptions = array(); diff --git a/includes/admin/reports/class-wcs-report-subscription-by-customer.php b/includes/admin/reports/class-wcs-report-subscription-by-customer.php index 390504b..4bad6ad 100644 --- a/includes/admin/reports/class-wcs-report-subscription-by-customer.php +++ b/includes/admin/reports/class-wcs-report-subscription-by-customer.php @@ -121,14 +121,23 @@ class WCS_Report_Subscription_By_Customer extends WP_List_Table { $this->totals = self::get_data(); - $customer_query = apply_filters( 'wcs_reports_current_customer_query', - "SELECT customer_ids.meta_value as customer_id, + $active_statuses = wcs_maybe_prefix_key( apply_filters( 'wcs_reports_active_statuses', [ 'active', 'pending-cancel' ] ), 'wc-' ); + $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, COALESCE( SUM(parent_total.meta_value), 0) as initial_order_total, COUNT(DISTINCT parent_order.ID) as initial_order_count, SUM(CASE 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 END) AS active_subscriptions 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' LEFT JOIN {$wpdb->posts} parent_order 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 ON parent_total.post_id = parent_order.ID 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') GROUP BY customer_ids.meta_value 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 + // 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', - "SELECT - customer_ids.meta_value as customer_id, - COALESCE( SUM(renewal_switch_totals.meta_value), 0) as renewal_switch_total, - 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 - AND subscription_posts.post_type = 'shop_subscription' - AND subscription_posts.post_status NOT IN ('wc-pending', 'trash') - INNER JOIN {$wpdb->postmeta} customer_ids - ON renewal_order_ids.meta_value = customer_ids.post_id - AND customer_ids.meta_key = '_customer_user' - AND customer_ids.meta_value IN ('" . implode( "','", wp_list_pluck( $this->items, 'customer_id' ) ) . "' ) - INNER JOIN {$wpdb->posts} renewal_order_posts - ON renewal_order_ids.post_id = renewal_order_posts.ID - AND renewal_order_posts.post_status IN ( 'wc-" . implode( "','wc-", apply_filters( 'woocommerce_reports_paid_order_statuses', array( 'completed', 'processing' ) ) ) . "' ) - LEFT JOIN {$wpdb->postmeta} renewal_switch_totals - ON renewal_switch_totals.post_id = renewal_order_ids.post_id - AND renewal_switch_totals.meta_key = '_order_total' - WHERE renewal_order_ids.meta_key = '_subscription_renewal' - OR renewal_order_ids.meta_key = '_subscription_switch' - GROUP BY customer_id - ORDER BY customer_id" + $wpdb->prepare( + "SELECT + customer_ids.meta_value as customer_id, + COALESCE( SUM(renewal_switch_totals.meta_value), 0) as renewal_switch_total, + 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 + AND subscription_posts.post_type = 'shop_subscription' + AND subscription_posts.post_status NOT IN ('wc-pending', 'trash') + INNER JOIN {$wpdb->postmeta} customer_ids + ON renewal_order_ids.meta_value = customer_ids.post_id + AND customer_ids.meta_key = '_customer_user' + AND customer_ids.meta_value IN ( {$customer_placeholders} ) + INNER JOIN {$wpdb->posts} renewal_order_posts + ON renewal_order_ids.post_id = renewal_order_posts.ID + AND renewal_order_posts.post_status IN ( {$status_placeholders} ) + LEFT JOIN {$wpdb->postmeta} renewal_switch_totals + ON renewal_switch_totals.post_id = renewal_order_ids.post_id + AND renewal_switch_totals.meta_key = '_order_total' + WHERE renewal_order_ids.meta_key = '_subscription_renewal' + OR renewal_order_ids.meta_key = '_subscription_switch' + 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 ); 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 = 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', - "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, COALESCE( SUM(parent_total.meta_value), 0) as initial_order_total, COUNT(DISTINCT parent_order.ID) as initial_order_count, COALESCE(SUM(CASE 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 END), 0) AS active_subscriptions 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' LEFT JOIN {$wpdb->posts} parent_order 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 ON parent_total.post_id = parent_order.ID AND parent_total.meta_key = '_order_total' WHERE subscription_posts.post_type = 'shop_subscription' 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__ ) ); $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 ] ) ) { // Enable big selects for reports $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 ) ); set_transient( strtolower( __CLASS__ ), $cached_results, WEEK_IN_SECONDS ); } $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', - "SELECT COALESCE( SUM(renewal_switch_totals.meta_value), 0) as renewal_switch_total, - COUNT(DISTINCT renewal_order_posts.ID) as renewal_switch_count - FROM {$wpdb->postmeta} renewal_order_ids - INNER JOIN {$wpdb->posts} subscription_posts + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Ignored for allowing interpolation in the IN statements. + $wpdb->prepare( + "SELECT COALESCE( SUM(renewal_switch_totals.meta_value), 0) as renewal_switch_total, + 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 AND subscription_posts.post_type = 'shop_subscription' AND subscription_posts.post_status NOT IN ('wc-pending', 'trash') INNER JOIN {$wpdb->posts} renewal_order_posts 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 ON renewal_switch_totals.post_id = renewal_order_ids.post_id AND renewal_switch_totals.meta_key = '_order_total' - WHERE renewal_order_ids.meta_key = '_subscription_renewal' - OR renewal_order_ids.meta_key = '_subscription_switch'" + WHERE renewal_order_ids.meta_key = '_subscription_renewal' + OR renewal_order_ids.meta_key = '_subscription_switch'", + $statuses + ) ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared. $query_hash = md5( $renewal_switch_total_query ); if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { // Enable big selects for reports $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 ) ); set_transient( strtolower( __CLASS__ ), $cached_results, WEEK_IN_SECONDS ); } diff --git a/includes/admin/reports/class-wcs-report-subscription-by-product.php b/includes/admin/reports/class-wcs-report-subscription-by-product.php index 59829f0..1337051 100644 --- a/includes/admin/reports/class-wcs-report-subscription-by-product.php +++ b/includes/admin/reports/class-wcs-report-subscription-by-product.php @@ -168,6 +168,7 @@ class WCS_Report_Subscription_By_Product extends WP_List_Table { if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { $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 ); 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 $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 INNER JOIN {$wpdb->posts} AS wcorders ON wcoitems.order_id = wcorders.ID 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 ON wcoimeta.order_item_id = wcoitems.order_item_id INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS wcoimeta2 ON wcoimeta2.order_item_id = wcoitems.order_item_id WHERE ( wcoimeta.meta_key = '_product_id' OR wcoimeta.meta_key = '_variation_id' ) 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 ); if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { $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 ); set_transient( strtolower( __CLASS__ ), $cached_results, WEEK_IN_SECONDS ); } diff --git a/includes/admin/reports/class-wcs-report-subscription-events-by-date.php b/includes/admin/reports/class-wcs-report-subscription-events-by-date.php index c6f14f1..7c87ad5 100644 --- a/includes/admin/reports/class-wcs-report-subscription-events-by-date.php +++ b/includes/admin/reports/class-wcs-report-subscription-events-by-date.php @@ -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 */ + // phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Ignored for allowing interpolation in the IN statements. $query = $wpdb->prepare( "SELECT SUM(subscriptions.count) as count, 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 LEFT JOIN {$wpdb->postmeta} AS order_total_post_meta ON order_posts.ID = order_total_post_meta.post_id - WHERE order_posts.post_type IN ( '" . implode( "','", wc_get_order_types( 'order-count' ) ) . "' ) - AND order_posts.post_status IN ( 'wc-" . implode( "','wc-", $args['order_status'] ) . "' ) + WHERE order_posts.post_type IN ( {$order_types_placeholders} ) + AND order_posts.post_status IN ( {$status_placeholders} ) AND order_posts.post_date >= %s AND order_posts.post_date < %s 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) ORDER BY post_date ASC", - date( 'Y-m-d', $this->start_date ), - $query_end_date, - date( 'Y-m-d', $this->start_date ), - $query_end_date + array_merge( + [ date( 'Y-m-d', $this->start_date ), $query_end_date ], + $order_types, + $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 ); if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { $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 ); $update_cache = true; } @@ -364,7 +374,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report { ) searchdate, {$wpdb->posts} AS wcsubs, {$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 wcsubs.post_type IN ( 'shop_subscription' ) 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 ] ) ) { $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 ); $update_cache = true; } @@ -397,7 +408,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report { * Subscription cancellations */ $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 JOIN {$wpdb->postmeta} AS wcsmeta_cancel 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 ) HAVING cancel_date BETWEEN %s AND %s ORDER BY wcsmeta_cancel.meta_value ASC", + $site_timezone, wcs_get_date_meta_key( 'cancelled' ), date( 'Y-m-d', $this->start_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 ] ) ) { $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 ); $update_cache = true; } @@ -427,7 +440,7 @@ class WCS_Report_Subscription_Events_By_Date extends WC_Admin_Report { * Subscriptions ended */ $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 JOIN {$wpdb->postmeta} AS wcsmeta_end 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 ) HAVING end_date BETWEEN %s AND %s ORDER BY wcsmeta_end.meta_value ASC", + $site_timezone, wcs_get_date_meta_key( 'end' ), date( 'Y-m-d', $this->start_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 ] ) ) { $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 ); $update_cache = true; } diff --git a/includes/admin/reports/class-wcs-report-subscription-payment-retry.php b/includes/admin/reports/class-wcs-report-subscription-payment-retry.php index e77504c..88d6c63 100644 --- a/includes/admin/reports/class-wcs-report-subscription-payment-retry.php +++ b/includes/admin/reports/class-wcs-report-subscription-payment-retry.php @@ -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 ) ) ); // Get the sum of order totals for completed retries (i.e. retries which eventually succeeded in processing the failed payment) - $renewal_query = $wpdb->prepare( - " - 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 - FROM {$wpdb->posts} AS orders - INNER JOIN {$wpdb->prefix}wcs_payment_retries AS retries ON ( orders.ID = retries.order_id ) - LEFT JOIN {$wpdb->postmeta} AS meta_order_total ON ( orders.ID = meta_order_total.post_id AND meta_order_total.meta_key = '_order_total' ) - WHERE retries.status = 'complete' - AND retries.date_gmt >= %s - AND retries.date_gmt < %s - GROUP BY {$this->group_by_query} - ORDER BY retry_date_gmt ASC - ", - $query_start_date, - $query_end_date + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- The $this->group_by_query clause is hard coded. + $this->report_data->renewal_data = $wpdb->get_results( + $wpdb->prepare( + " + 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 + FROM {$wpdb->posts} AS orders + INNER JOIN {$wpdb->prefix}wcs_payment_retries AS retries ON ( orders.ID = retries.order_id ) + LEFT JOIN {$wpdb->postmeta} AS meta_order_total ON ( orders.ID = meta_order_total.post_id AND meta_order_total.meta_key = '_order_total' ) + WHERE retries.status = 'complete' + AND retries.date_gmt >= %s + AND retries.date_gmt < %s + GROUP BY {$this->group_by_query} + ORDER BY retry_date_gmt ASC + ", + $retry_date_in_local_time, + $query_start_date, + $query_end_date + ) ); - - $this->report_data->renewal_data = $wpdb->get_results( $renewal_query ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared // Get the counts for all retries, grouped by day or month and status - $retry_query = $wpdb->prepare( - " - 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 - FROM {$wpdb->prefix}wcs_payment_retries AS retries - WHERE retries.status IN ( 'complete', 'failed', 'pending' ) - AND retries.date_gmt >= %s - AND retries.date_gmt < %s - GROUP BY {$this->group_by_query}, status - ORDER BY retry_date_gmt ASC - ", - $query_start_date, - $query_end_date + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- The $this->group_by_query clause is hard coded. + $this->report_data->retry_data = $wpdb->get_results( + $wpdb->prepare( + " + 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 + FROM {$wpdb->prefix}wcs_payment_retries AS retries + WHERE retries.status IN ( 'complete', 'failed', 'pending' ) + AND retries.date_gmt >= %s + AND retries.date_gmt < %s + GROUP BY {$this->group_by_query}, status + ORDER BY retry_date_gmt ASC + ", + $retry_date_in_local_time, + $query_start_date, + $query_end_date + ) ); - - $this->report_data->retry_data = $wpdb->get_results( $retry_query ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared // 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' ) ) ); diff --git a/includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php b/includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php index ccd3540..a1077d0 100644 --- a/includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php +++ b/includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php @@ -130,6 +130,7 @@ class WCS_Report_Upcoming_Recurring_Revenue extends WC_Admin_Report { $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 + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- The $this->group_by_query clause is hard coded. $base_query = $wpdb->prepare( "SELECT 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 mo.meta_key = '_order_total' 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 mp.meta_key = '_billing_period' 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', strtotime( '+1 DAY', $this->end_date ) ) ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared $cached_results = get_transient( strtolower( get_class( $this ) ) ); $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 ] ) ) { $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 ); set_transient( strtolower( get_class( $this ) ), $cached_results, WEEK_IN_SECONDS ); } diff --git a/includes/early-renewal/class-wcs-early-renewal-modal-handler.php b/includes/early-renewal/class-wcs-early-renewal-modal-handler.php index 2990501..8a184ae 100644 --- a/includes/early-renewal/class-wcs-early-renewal-modal-handler.php +++ b/includes/early-renewal/class-wcs-early-renewal-modal-handler.php @@ -148,7 +148,7 @@ class WCS_Early_Renewal_Modal_Handler { if ( $renewal_order->needs_payment() ) { $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' ); - wp_redirect( wcs_get_early_renewal_url( $subscription ) ); + wp_safe_redirect( wcs_get_early_renewal_url( $subscription ) ); exit(); } @@ -191,7 +191,7 @@ class WCS_Early_Renewal_Modal_Handler { * @since 2.6.0 */ 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(); } diff --git a/includes/payment-retry/data-stores/class-wcs-retry-database-store.php b/includes/payment-retry/data-stores/class-wcs-retry-database-store.php index 0f9f48d..8c9db94 100644 --- a/includes/payment-retry/data-stores/class-wcs-retry-database-store.php +++ b/includes/payment-retry/data-stores/class-wcs-retry-database-store.php @@ -94,7 +94,8 @@ class WCS_Retry_Database_Store extends WCS_Retry_Store { $retry = null; $raw_retry = $wpdb->get_row( $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 ) ); @@ -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']}" ) ); $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(); + $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 ) { if ( 'ids' === $return ) { diff --git a/includes/switching/class-wc-subscriptions-switcher.php b/includes/switching/class-wc-subscriptions-switcher.php index 043d40a..5ebf711 100644 --- a/includes/switching/class-wc-subscriptions-switcher.php +++ b/includes/switching/class-wc-subscriptions-switcher.php @@ -183,12 +183,13 @@ class WC_Subscriptions_Switcher { if ( isset( $_GET['switch-subscription'] ) && isset( $_GET['item'] ) ) { $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 - 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(); } else { @@ -238,7 +239,7 @@ class WC_Subscriptions_Switcher { 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' ); - wp_redirect( wc_get_cart_url() ); + wp_safe_redirect( wc_get_cart_url() ); exit(); } } 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 ) ) { - 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; } } @@ -1456,7 +1457,7 @@ class WC_Subscriptions_Switcher { 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()->cart->empty_cart( true ); - wp_redirect( get_permalink( $product_id ) ); + wp_safe_redirect( get_permalink( $product_id ) ); exit(); } @@ -1497,7 +1498,7 @@ class WC_Subscriptions_Switcher { wc_add_notice( __( 'There was an error locating the switch details.', 'woocommerce-subscriptions' ), 'error' ); 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(); } } diff --git a/languages/woocommerce-subscriptions.pot b/languages/woocommerce-subscriptions.pot index 620f8ef..0126190 100644 --- a/languages/woocommerce-subscriptions.pot +++ b/languages/woocommerce-subscriptions.pot @@ -2,38 +2,43 @@ # This file is distributed under the same license as the WooCommerce Subscriptions plugin. msgid "" msgstr "" -"Project-Id-Version: WooCommerce Subscriptions 7.3.1\n" +"Project-Id-Version: WooCommerce Subscriptions 7.4.0\n" "Report-Msgid-Bugs-To: https://woocommerce.com/contact-us\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2025-03-31T01:31:21+00:00\n" +"POT-Creation-Date: 2025-04-14T15:37:51+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.11.0\n" "X-Domain: woocommerce-subscriptions\n" #. Plugin Name of the plugin +#: woocommerce-subscriptions.php #: vendor/woocommerce/subscriptions-core/includes/privacy/class-wcs-privacy.php:49 msgid "WooCommerce Subscriptions" msgstr "" #. Plugin URI of the plugin +#: woocommerce-subscriptions.php msgid "https://www.woocommerce.com/products/woocommerce-subscriptions/" msgstr "" #. Description of the plugin +#: woocommerce-subscriptions.php msgid "Sell products and services with recurring payments in your WooCommerce Store." msgstr "" #. Author of the plugin +#: woocommerce-subscriptions.php #: includes/admin/class-wcs-admin-reports.php:136 #: includes/admin/reports/class-wcs-report-cache-manager.php:267 msgid "WooCommerce" msgstr "" #. Author URI of the plugin +#: woocommerce-subscriptions.php msgid "https://woocommerce.com/" msgstr "" @@ -48,10 +53,10 @@ msgid "Subscription reports are incompatible with the %1$sWooCommerce data stora msgstr "" #: includes/admin/class-wcs-admin-reports.php:81 -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:923 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:938 #: includes/api/class-wc-rest-subscriptions-settings.php:29 -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1028 -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1180 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1030 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1182 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-system-status.php:100 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-wc-admin-manager.php:41 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-wc-admin-manager.php:51 @@ -99,14 +104,14 @@ msgid "Report Cache Enabled" msgstr "" #: includes/admin/reports/class-wcs-report-cache-manager.php:321 -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1722 -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1791 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1724 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1793 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-system-status.php:139 msgid "Yes" msgstr "" #: includes/admin/reports/class-wcs-report-cache-manager.php:321 -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1722 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1724 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-system-status.php:139 msgid "No" msgstr "" @@ -123,52 +128,52 @@ msgstr[0] "" msgstr[1] "" #. translators: 1$: count, 2$ and 3$ are opening and closing strong tags, respectively. -#: includes/admin/reports/class-wcs-report-dashboard.php:221 +#: includes/admin/reports/class-wcs-report-dashboard.php:227 msgid "%2$s%1$s signup%3$s subscription signups this month" msgid_plural "%2$s%1$s signups%3$s subscription signups this month" msgstr[0] "" msgstr[1] "" #. translators: %s: formatted amount. -#: includes/admin/reports/class-wcs-report-dashboard.php:229 +#: includes/admin/reports/class-wcs-report-dashboard.php:235 msgid "%s signup revenue this month" msgstr "" #. translators: 1$: count, 2$ and 3$ are opening and closing strong tags, respectively. -#: includes/admin/reports/class-wcs-report-dashboard.php:237 +#: includes/admin/reports/class-wcs-report-dashboard.php:243 msgid "%2$s%1$s renewal%3$s subscription renewals this month" msgid_plural "%2$s%1$s renewals%3$s subscription renewals this month" msgstr[0] "" msgstr[1] "" #. translators: %s: formatted amount. -#: includes/admin/reports/class-wcs-report-dashboard.php:245 +#: includes/admin/reports/class-wcs-report-dashboard.php:251 msgid "%s renewal revenue this month" msgstr "" #. translators: 1$: count, 2$ and 3$ are opening and closing strong tags, respectively. -#: includes/admin/reports/class-wcs-report-dashboard.php:253 +#: includes/admin/reports/class-wcs-report-dashboard.php:259 msgid "%2$s%1$s cancellation%3$s subscription cancellations this month" msgid_plural "%2$s%1$s cancellations%3$s subscription cancellations this month" msgstr[0] "" msgstr[1] "" -#: includes/admin/reports/class-wcs-report-retention-rate.php:156 +#: includes/admin/reports/class-wcs-report-retention-rate.php:158 msgctxt "X axis label on retention rate graph" msgid "Number of days after sign-up" msgstr "" -#: includes/admin/reports/class-wcs-report-retention-rate.php:159 +#: includes/admin/reports/class-wcs-report-retention-rate.php:161 msgctxt "X axis label on retention rate graph" msgid "Number of weeks after sign-up" msgstr "" -#: includes/admin/reports/class-wcs-report-retention-rate.php:162 +#: includes/admin/reports/class-wcs-report-retention-rate.php:164 msgctxt "X axis label on retention rate graph" msgid "Number of months after sign-up" msgstr "" -#: includes/admin/reports/class-wcs-report-retention-rate.php:226 +#: includes/admin/reports/class-wcs-report-retention-rate.php:228 msgid "Unended Subscription Count" msgstr "" @@ -315,271 +320,271 @@ msgstr "" msgid "The average line total on all orders for this product line item." msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-by-product.php:305 -#: includes/admin/reports/class-wcs-report-subscription-by-product.php:345 +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:316 +#: includes/admin/reports/class-wcs-report-subscription-by-product.php:356 msgid "subscriptions" msgstr "" #. translators: %s: formatted total amount. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:494 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:509 msgid "%s signup revenue in this period" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:495 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:510 msgid "The sum of all subscription parent orders, including other items, fees, tax and shipping." msgstr "" #. translators: %s: formatted total amount. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:502 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:517 msgid "%s renewal revenue in this period" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:503 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:518 msgid "The sum of all renewal orders including tax and shipping." msgstr "" #. translators: %s: formatted total amount. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:510 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:525 msgid "%s resubscribe revenue in this period" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:511 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:526 msgid "The sum of all resubscribe orders including tax and shipping." msgstr "" #. translators: %s: formatted total amount. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:518 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:533 msgid "%s switch revenue in this period" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:519 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:534 msgid "The sum of all switch orders including tax and shipping." msgstr "" #. translators: 2: link opening tag, 1: subscription count and closing tag. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:527 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:542 msgid "%2$s %1$s new subscriptions" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:541 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:556 msgid "The number of subscriptions created during this period, either by being manually created, imported or a customer placing an order. This includes orders pending payment." msgstr "" #. translators: 2: link opening tag, 1: subscription count and closing tag. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:549 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:564 msgid "%2$s %1$s subscription signups" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:563 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:578 msgid "The number of subscriptions purchased in parent orders created during this period. This represents the new subscriptions created by customers placing an order via checkout." msgstr "" #. translators: 2: link opening tag, 1: subscription count and closing tag. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:571 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:586 msgid "%2$s %1$s subscription resubscribes" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:585 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:600 msgid "The number of resubscribe orders processed during this period." msgstr "" #. translators: 2: link opening tag, 1: subscription count and closing tag. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:593 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:608 msgid "%2$s %1$s subscription renewals" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:607 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:622 msgid "The number of renewal orders processed during this period." msgstr "" #. translators: 2: link opening tag, 1: subscription count and closing tag. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:615 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:630 msgid "%2$s %1$s subscription switches" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:629 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:644 msgid "The number of subscriptions upgraded, downgraded or cross-graded during this period." msgstr "" #. translators: 2: link opening tag, 1: subscription count and closing tag. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:637 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:652 msgid "%2$s %1$s subscription cancellations" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:651 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:666 msgid "The number of subscriptions cancelled by the customer or store manager during this period. The pre-paid term may not yet have ended during this period." msgstr "" #. translators: 2: link opening tag, 1: subscription count and closing tag. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:659 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:674 msgid "%2$s %1$s ended subscriptions" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:673 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:688 msgid "The number of subscriptions which have either expired or reached the end of the prepaid term if it was previously cancelled." msgstr "" #. translators: 2: link opening tag, 1: subscription count and closing tag. -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:684 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:699 msgid "%2$s %1$s current subscriptions" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:699 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:714 msgid "The number of subscriptions during this period with an end date in the future and a status other than pending." msgstr "" #. translators: %s: subscription net gain (with percentage). -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:716 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:731 msgid "%s net subscription gain" msgstr "" #. translators: %s: subscription net loss (with percentage). -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:719 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:734 msgid "%s net subscription loss" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:724 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:739 msgid "Change in subscriptions between the start and end of the period." msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:738 -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:159 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:753 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:165 msgid "Year" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:739 -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:160 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:754 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:166 msgid "Last Month" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:740 -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:161 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:755 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:167 msgid "This Month" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:741 -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:162 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:756 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:168 msgid "Last 7 Days" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:782 -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:195 -#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:222 -#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-table.php:20 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:797 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:201 +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:225 +#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-table.php:16 #: vendor/woocommerce/subscriptions-core/templates/myaccount/related-orders.php:23 #: vendor/woocommerce/subscriptions-core/templates/myaccount/related-orders.php:48 msgid "Date" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:786 -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:199 -#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:226 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:801 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:205 +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:229 msgid "Export CSV" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:845 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:860 msgid "Switched subscriptions" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:861 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:876 msgid "New Subscriptions" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:877 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:892 msgid "Subscriptions signups" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:892 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:907 msgid "Number of resubscribes" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:907 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:922 msgid "Number of renewals" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:939 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:954 msgid "Subscriptions Ended" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:955 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:970 msgid "Cancellations" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:970 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:985 msgid "Signup Totals" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:990 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:1005 msgid "Resubscribe Totals" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:1010 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:1025 msgid "Renewal Totals" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:1030 +#: includes/admin/reports/class-wcs-report-subscription-events-by-date.php:1045 msgid "Switch Totals" msgstr "" #. translators: %s: formatted amount. -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:113 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:119 msgid "%s renewal revenue recovered" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:114 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:120 msgid "The total amount of revenue, including tax and shipping, recovered with the failed payment retry system for renewal orders with a failed payment." msgstr "" #. translators: %s: renewal count. -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:121 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:127 #: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:104 msgid "%s renewal orders" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:122 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:128 msgid "The number of renewal orders which had a failed payment use the retry system." msgstr "" #. translators: %s: retry count. -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:128 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:134 msgid "%s retry attempts succeeded" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:129 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:135 msgid "The number of renewal payment retries for this period which were able to process the payment which had previously failed one or more times." msgstr "" #. translators: %s: retry count. -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:136 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:142 msgid "%s retry attempts failed" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:137 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:143 msgid "The number of renewal payment retries for this period which did not result in a successful payment." msgstr "" #. translators: %s: retry count. -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:144 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:150 msgid "%s retry attempts pending" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:145 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:151 msgid "The number of renewal payment retries not yet processed." msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:247 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:253 msgid "Successful retries" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:263 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:269 msgid "Failed retries" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:279 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:285 msgid "Pending retries" msgstr "" -#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:295 +#: includes/admin/reports/class-wcs-report-subscription-payment-retry.php:301 msgid "Recovered Renewal Revenue" msgstr "" @@ -601,27 +606,27 @@ msgstr "" msgid "%s average renewal amount" msgstr "" -#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:192 +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:195 msgid "Next 12 Months" msgstr "" -#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:193 +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:196 msgid "Next 30 Days" msgstr "" -#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:194 +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:197 msgid "Next Month" msgstr "" -#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:195 +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:198 msgid "Next 7 Days" msgstr "" -#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:260 +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:263 msgid "Renewals count" msgstr "" -#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:269 +#: includes/admin/reports/class-wcs-report-upcoming-recurring-revenue.php:272 msgid "Renewals amount" msgstr "" @@ -1334,7 +1339,7 @@ msgstr "" #. translators: %s: order number. #: includes/early-renewal/class-wcs-cart-early-renewal.php:222 #: includes/early-renewal/wcs-early-renewal-functions.php:136 -#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-row.php:18 +#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-row.php:16 #: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-unknown-related-orders-row.php:18 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-renewal-order.php:154 #: vendor/woocommerce/subscriptions-core/templates/myaccount/my-subscriptions.php:36 @@ -1560,7 +1565,7 @@ msgid "Y/m/d g:i:s A" msgstr "" #: includes/payment-retry/admin/html-retries-table.php:47 -#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-row.php:33 +#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-row.php:29 msgid "Unpublished" msgstr "" @@ -1682,218 +1687,218 @@ msgstr "" msgid "[{site_title}] Automatic payment failed for {order_number}, retry scheduled to run {retry_time}" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:197 +#: includes/switching/class-wc-subscriptions-switcher.php:198 msgid "You have a subscription to this product. Choosing a new subscription will replace your existing subscription." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:199 +#: includes/switching/class-wc-subscriptions-switcher.php:200 msgid "Choose a new subscription." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:239 -#: includes/switching/class-wc-subscriptions-switcher.php:1254 +#: includes/switching/class-wc-subscriptions-switcher.php:240 +#: includes/switching/class-wc-subscriptions-switcher.php:1255 msgid "Your cart contained an invalid subscription switch request. It has been removed." msgid_plural "Your cart contained invalid subscription switch requests. They have been removed." msgstr[0] "" msgstr[1] "" -#: includes/switching/class-wc-subscriptions-switcher.php:281 +#: includes/switching/class-wc-subscriptions-switcher.php:282 msgid "You have already subscribed to this product and it is limited to one per customer. You can not purchase the product again." msgstr "" #. translators: 1$: is the "You have already subscribed to this product" notice, 2$-4$: opening/closing link tags, 3$: an order number -#: includes/switching/class-wc-subscriptions-switcher.php:290 +#: includes/switching/class-wc-subscriptions-switcher.php:291 msgid "%1$s Complete payment on %2$sOrder %3$s%4$s to be able to change your subscription." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:384 +#: includes/switching/class-wc-subscriptions-switcher.php:385 msgid "Switching" msgstr "" #. translators: placeholders are opening and closing link tags -#: includes/switching/class-wc-subscriptions-switcher.php:387 +#: includes/switching/class-wc-subscriptions-switcher.php:388 msgid "Allow subscribers to switch (upgrade or downgrade) between different subscriptions. %1$sLearn more%2$s." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:395 +#: includes/switching/class-wc-subscriptions-switcher.php:396 msgid "Prorate Recurring Payment" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:396 +#: includes/switching/class-wc-subscriptions-switcher.php:397 msgid "When switching to a subscription with a different recurring payment or billing period, should the price paid for the existing billing period be prorated when switching to the new subscription?" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:404 -#: includes/switching/class-wc-subscriptions-switcher.php:438 +#: includes/switching/class-wc-subscriptions-switcher.php:405 +#: includes/switching/class-wc-subscriptions-switcher.php:439 msgctxt "when to allow a setting" msgid "Never" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:405 +#: includes/switching/class-wc-subscriptions-switcher.php:406 msgctxt "when to prorate recurring fee when switching" msgid "For Upgrades of Virtual Subscription Products Only" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:406 +#: includes/switching/class-wc-subscriptions-switcher.php:407 msgctxt "when to prorate recurring fee when switching" msgid "For Upgrades of All Subscription Products" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:407 +#: includes/switching/class-wc-subscriptions-switcher.php:408 msgctxt "when to prorate recurring fee when switching" msgid "For Upgrades & Downgrades of Virtual Subscription Products Only" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:408 +#: includes/switching/class-wc-subscriptions-switcher.php:409 msgctxt "when to prorate recurring fee when switching" msgid "For Upgrades & Downgrades of All Subscription Products" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:413 +#: includes/switching/class-wc-subscriptions-switcher.php:414 msgid "Prorate Sign up Fee" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:414 +#: includes/switching/class-wc-subscriptions-switcher.php:415 msgid "When switching to a subscription with a sign up fee, you can require the customer pay only the gap between the existing subscription's sign up fee and the new subscription's sign up fee (if any)." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:422 -msgctxt "when to prorate signup fee when switching" -msgid "Never (do not charge a sign up fee)" -msgstr "" - #: includes/switching/class-wc-subscriptions-switcher.php:423 msgctxt "when to prorate signup fee when switching" -msgid "Never (charge the full sign up fee)" +msgid "Never (do not charge a sign up fee)" msgstr "" #: includes/switching/class-wc-subscriptions-switcher.php:424 msgctxt "when to prorate signup fee when switching" +msgid "Never (charge the full sign up fee)" +msgstr "" + +#: includes/switching/class-wc-subscriptions-switcher.php:425 +msgctxt "when to prorate signup fee when switching" msgid "Always" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:429 +#: includes/switching/class-wc-subscriptions-switcher.php:430 msgid "Prorate Subscription Length" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:430 +#: includes/switching/class-wc-subscriptions-switcher.php:431 msgid "When switching to a subscription with a length, you can take into account the payments already completed by the customer when determining how many payments the subscriber needs to make for the new subscription." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:439 +#: includes/switching/class-wc-subscriptions-switcher.php:440 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-synchroniser.php:226 msgctxt "when to prorate first payment / subscription length" msgid "For Virtual Subscription Products Only" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:440 +#: includes/switching/class-wc-subscriptions-switcher.php:441 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-synchroniser.php:227 msgctxt "when to prorate first payment / subscription length" msgid "For All Subscription Products" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:445 +#: includes/switching/class-wc-subscriptions-switcher.php:446 msgid "Switch Button Text" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:446 +#: includes/switching/class-wc-subscriptions-switcher.php:447 msgid "Customise the text displayed on the button next to the subscription on the subscriber's account page. The default is \"Switch Subscription\", but you may wish to change this to \"Upgrade\" or \"Change Subscription\"." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:450 -#: includes/switching/class-wc-subscriptions-switcher.php:552 +#: includes/switching/class-wc-subscriptions-switcher.php:451 +#: includes/switching/class-wc-subscriptions-switcher.php:553 msgid "Upgrade or Downgrade" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:489 +#: includes/switching/class-wc-subscriptions-switcher.php:490 msgid "Allow Switching" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:496 +#: includes/switching/class-wc-subscriptions-switcher.php:497 msgctxt "when to allow switching" msgid "Between Subscription Variations" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:500 +#: includes/switching/class-wc-subscriptions-switcher.php:501 msgctxt "when to allow switching" msgid "Between Grouped Subscriptions" msgstr "" #. translators: %s: order number. -#: includes/switching/class-wc-subscriptions-switcher.php:1163 +#: includes/switching/class-wc-subscriptions-switcher.php:1164 msgid "Switch order cancelled due to a new switch order being created #%s." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:1382 +#: includes/switching/class-wc-subscriptions-switcher.php:1383 msgid "You can only switch to a subscription product." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:1388 +#: includes/switching/class-wc-subscriptions-switcher.php:1389 msgid "We can not find your old subscription item." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:1410 +#: includes/switching/class-wc-subscriptions-switcher.php:1411 msgid "You can not switch to the same subscription." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:1457 +#: includes/switching/class-wc-subscriptions-switcher.php:1458 msgid "You can not switch this subscription. It appears you do not own the subscription." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:1498 +#: includes/switching/class-wc-subscriptions-switcher.php:1499 msgid "There was an error locating the switch details." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:1846 +#: includes/switching/class-wc-subscriptions-switcher.php:1847 msgctxt "a switch type" msgid "Downgrade" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:1849 +#: includes/switching/class-wc-subscriptions-switcher.php:1850 msgctxt "a switch type" msgid "Upgrade" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:1852 +#: includes/switching/class-wc-subscriptions-switcher.php:1853 msgctxt "a switch type" msgid "Crossgrade" msgstr "" #. translators: %1: product subtotal, %2: HTML span tag, %3: direction (upgrade, downgrade, crossgrade), %4: closing HTML span tag -#: includes/switching/class-wc-subscriptions-switcher.php:1857 +#: includes/switching/class-wc-subscriptions-switcher.php:1858 msgctxt "product subtotal string" msgid "%1$s %2$s(%3$s)%4$s" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:1973 +#: includes/switching/class-wc-subscriptions-switcher.php:1974 msgid "The original subscription item being switched cannot be found." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:1975 +#: includes/switching/class-wc-subscriptions-switcher.php:1976 msgid "The item on the switch order cannot be found." msgstr "" #. translators: 1$: old item, 2$: new item when switching -#: includes/switching/class-wc-subscriptions-switcher.php:1986 +#: includes/switching/class-wc-subscriptions-switcher.php:1987 msgctxt "used in order notes" msgid "Customer switched from: %1$s to %2$s." msgstr "" #. translators: %s: new item name. -#: includes/switching/class-wc-subscriptions-switcher.php:1989 +#: includes/switching/class-wc-subscriptions-switcher.php:1990 msgctxt "used in order notes" msgid "Customer added %s." msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:2384 +#: includes/switching/class-wc-subscriptions-switcher.php:2385 msgid "Switch Order" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:2399 +#: includes/switching/class-wc-subscriptions-switcher.php:2400 msgid "Switched Subscription" msgstr "" -#: includes/switching/class-wc-subscriptions-switcher.php:2581 +#: includes/switching/class-wc-subscriptions-switcher.php:2582 msgctxt "add to cart button text while switching a subscription" msgid "Switch subscription" msgstr "" @@ -1924,46 +1929,6 @@ msgstr "" msgid "Want to renew early via the checkout? Click %shere.%s" msgstr "" -#: tests/unit/scheduler/scheduler.php:65 -#: vendor/woocommerce/subscriptions-core/wcs-functions.php:290 -msgctxt "table heading" -msgid "Start Date" -msgstr "" - -#: tests/unit/scheduler/scheduler.php:66 -#: vendor/woocommerce/subscriptions-core/wcs-functions.php:291 -msgctxt "table heading" -msgid "Trial End" -msgstr "" - -#: tests/unit/scheduler/scheduler.php:67 -#: vendor/woocommerce/subscriptions-core/templates/myaccount/my-subscriptions.php:43 -#: vendor/woocommerce/subscriptions-core/wcs-functions.php:292 -msgctxt "table heading" -msgid "Next Payment" -msgstr "" - -#: tests/unit/scheduler/scheduler.php:68 -#: vendor/woocommerce/subscriptions-core/templates/emails/cancelled-subscription.php:41 -#: vendor/woocommerce/subscriptions-core/templates/emails/expired-subscription.php:26 -#: vendor/woocommerce/subscriptions-core/templates/emails/on-hold-subscription.php:26 -#: vendor/woocommerce/subscriptions-core/wcs-functions.php:293 -msgctxt "table heading" -msgid "Last Order Date" -msgstr "" - -#: tests/unit/scheduler/scheduler.php:69 -#: vendor/woocommerce/subscriptions-core/wcs-functions.php:294 -msgctxt "table heading" -msgid "Cancelled Date" -msgstr "" - -#: tests/unit/scheduler/scheduler.php:70 -#: vendor/woocommerce/subscriptions-core/wcs-functions.php:295 -msgctxt "table heading" -msgid "End Date" -msgstr "" - #. translators: 1: relation type, 2: list of valid relation types. #: vendor/woocommerce/subscriptions-core/includes/abstracts/abstract-wcs-related-order-store.php:148 msgid "Invalid relation type: %1$s. Order relationship type must be one of: %2$s." @@ -1986,6 +1951,7 @@ msgid "Virtual" msgstr "" #: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:298 +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:25 msgid "Choose the subscription price, billing interval and period." msgstr "" @@ -1998,133 +1964,129 @@ msgstr "" #. translators: %s: currency symbol. #. translators: placeholder is a currency symbol / code #: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:315 -#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:44 +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:23 msgid "Subscription price (%s)" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:319 +#. Translators: %s: formatted example price value. +#. translators: %s the formatted example price value. +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:320 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:359 +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:30 msgctxt "example price" -msgid "e.g. 5.90" +msgid "e.g. %s" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:320 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:321 msgid "Subscription interval" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:326 -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:482 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:327 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:484 msgid "Subscription period" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:342 -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:483 -#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:66 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:343 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:485 +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:50 msgid "Stop renewing after" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:345 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:346 msgid "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." msgstr "" #. translators: %s is a currency symbol / code -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:356 -#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:20 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:357 +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:63 msgid "Sign-up fee (%s)" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:357 -#: vendor/woocommerce/subscriptions-core/templates/admin/deprecated/html-variation-price.php:31 -#: vendor/woocommerce/subscriptions-core/templates/admin/deprecated/html-variation-price.php:86 -#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:21 -#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:47 -msgctxt "example price" -msgid "e.g. 9.90" -msgstr "" - -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:358 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:360 +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:64 msgid "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." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:372 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:374 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-cart.php:2416 -#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:25 +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:70 msgid "Free trial" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:375 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:377 #: vendor/woocommerce/subscriptions-core/templates/admin/deprecated/html-variation-price.php:115 msgid "Subscription Trial Period" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:415 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:417 msgid "One time shipping" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:416 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:418 msgid "Shipping for subscription products is normally charged on the initial order and all renewal orders. Enable this to only charge shipping once on the initial order. Note: for this setting to be enabled the subscription must not have a free trial or a synced renewal date." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:479 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:481 msgid "Subscription pricing" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:480 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:482 msgid "Subscription sign-up fee" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:481 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:483 msgid "Subscription billing interval" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:484 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:486 msgid "Free trial length" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:485 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:487 msgid "Free trial period" msgstr "" #. translators: %s: subscription status. -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:808 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:810 msgid "Unable to change subscription status to \"%s\". Please assign a customer to the subscription to activate it." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:862 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:864 msgid "Trashing this order will also trash the subscriptions purchased with the order." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:875 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:877 msgid "Enter the new period, either day, week, month or year:" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:876 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:878 msgid "Enter a new length (e.g. 5):" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:877 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:879 msgid "Enter a new interval as a single number (e.g. to charge every 2nd month, enter 2):" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:878 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:880 msgid "Delete all variations without a subscription" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:884 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:886 msgid "An error occurred determining if that variation can be deleted. Please try again." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:885 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:887 msgid "That variation can not be removed because it is associated with active subscriptions. To remove this variation, please cancel and delete the subscriptions for it." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:890 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:892 msgid "" "You are about to trash one or more orders which contain a subscription.\n" "\n" "Trashing the orders will also trash the subscriptions purchased with these orders." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:898 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:900 msgid "" "WARNING: Bad things are about to happen!\n" "\n" @@ -2133,179 +2095,179 @@ msgid "" "Changes to the billing period, recurring discount, recurring tax or recurring total may not be reflected in the amount charged by the payment gateway." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:899 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:901 msgid "You are deleting a subscription item. You will also need to manually cancel and trash the subscription on the Manage Subscriptions screen." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:906 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:908 msgid "" "Warning: Deleting a user will also delete the user's subscriptions. The user's orders will remain but be reassigned to the 'Guest' user.\n" "\n" "Do you want to continue to delete this user and any associated subscriptions?" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:910 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:912 msgid "PayPal Standard has a number of limitations and does not support all subscription features." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:910 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:912 msgid "Because of this, it is not recommended as a payment method for Subscriptions unless it is the only available option for your country." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:913 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:915 msgid "This action cannot be reversed. Are you sure you wish to erase personal data from the selected subscriptions?" msgstr "" #. translators: placeholders are for HTML tags. They are 1$: "

", 2$: "

", 3$: "

", 4$: "", 5$: "", 6$: "", 7$: "", 8$: "

" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:930 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:932 msgctxt "used in admin pointer script params in javascript as type pointer content" msgid "%1$sChoose Subscription%2$s%3$sThe WooCommerce Subscriptions extension adds two new subscription product types - %4$sSimple subscription%5$s and %6$sVariable subscription%7$s.%8$s" msgstr "" #. translators: placeholders are for HTML tags. They are 1$: "

", 2$: "

", 3$: "

", 4$: "

" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:932 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:934 msgctxt "used in admin pointer script params in javascript as price pointer content" msgid "%1$sSet a Price%2$s%3$sSubscription prices are a little different to other product prices. For a subscription, you can set a billing period, length, sign-up fee and free trial.%4$s" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:958 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:960 msgid "Active subscriber?" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1002 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1004 msgid "Manage Subscriptions" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1006 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1008 #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-core-plugin.php:402 msgid "Search Subscriptions" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1232 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1234 msgctxt "options section heading" msgid "Miscellaneous" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1239 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1241 msgid "Mixed Checkout" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1240 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1242 msgid "Allow multiple subscriptions and products to be purchased simultaneously." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1244 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1246 msgid "Allow a subscription product to be purchased with other products and subscriptions in the same transaction." msgstr "" #. translators: placeholder is a number #. translators: placeholder is a subscription ID. -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1346 -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1588 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1348 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1590 msgid "We can't find a subscription with ID #%d. Perhaps it was deleted?" msgstr "" #. translators: Placeholders are opening and closing link tags. -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1439 -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1501 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1441 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1503 msgid "We weren't able to locate the set of report results you requested. Please regenerate the link from the %1$sSubscription Reports screen%2$s." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1556 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1558 msgid "We can't find a paid subscription order for this user." msgstr "" #. translators: placeholders are opening link tag, ID of sub, and closing link tag -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1595 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1597 msgid "Showing orders for %1$sSubscription %2$s%3$s" msgstr "" #. translators: number of 1$: days, 2$: weeks, 3$: months, 4$: years -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1618 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1620 msgid "The trial period can not exceed: %1$s, %2$s, %3$s or %4$s." msgstr "" #. translators: placeholder is a time period (e.g. "4 weeks") -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1623 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1625 msgid "The trial period can not exceed %s." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1648 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1650 msgid "Please log in to your account to view your subscriptions." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1685 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1687 msgid "No subscriptions found for that customer." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1687 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1689 msgid "You do not have permission to view those subscriptions." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1721 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1723 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-system-status.php:137 msgctxt "label that indicates whether debugging is turned on for the plugin" msgid "WCS_DEBUG" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1727 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1729 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-system-status.php:151 msgctxt "Live or Staging, Label on WooCommerce -> System Status page" msgid "Subscriptions Mode" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1728 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1730 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-system-status.php:153 msgctxt "refers to staging site" msgid "Staging" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1728 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1730 #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-system-status.php:153 msgctxt "refers to live site" msgid "Live" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1758 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1760 msgid "Automatic Recurring Payments" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1791 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1793 msgid "Supports automatic renewal payments." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1872 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1874 msgid "Subscription items can no longer be edited." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1877 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1879 msgid "This subscription is no longer editable because the payment gateway does not allow modification of recurring amounts." msgstr "" #. translators: $1-2: opening and closing tags of a link that takes to Woo marketplace / Stripe product page -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1896 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1898 msgid "No payment gateways capable of processing automatic subscription payments are enabled. If you would like to process automatic payments, we recommend %1$sWooPayments%2$s." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1903 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1905 msgid "Recurring Payments" msgstr "" #. translators: placeholders are opening and closing link tags -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1911 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:1913 msgid "Payment gateways which don't support automatic recurring payments can be used to process %1$smanual subscription renewal payments%2$s." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:2031 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:2033 msgid "Note that purchasing a subscription still requires an account." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:2045 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:2047 msgid "The product type can not be changed because this product is associated with subscriptions." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:2102 -#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:2103 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:2104 +#: vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php:2105 msgid "Allow subscription customers to create an account during checkout" msgstr "" @@ -2486,7 +2448,7 @@ msgstr[0] "" msgstr[1] "" #: vendor/woocommerce/subscriptions-core/includes/admin/class-wcs-admin-post-types.php:468 -#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-table.php:21 +#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-table.php:17 #: vendor/woocommerce/subscriptions-core/templates/myaccount/my-subscriptions.php:22 #: vendor/woocommerce/subscriptions-core/templates/myaccount/my-subscriptions.php:40 #: vendor/woocommerce/subscriptions-core/templates/myaccount/related-orders.php:24 @@ -3026,20 +2988,20 @@ msgid "Error updating some information: %s" msgstr "" #. translators: placeholder is an order number. -#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-row.php:15 +#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-row.php:14 msgid "Edit order number %s" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-table.php:18 +#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-table.php:14 #: vendor/woocommerce/subscriptions-core/templates/myaccount/related-orders.php:42 msgid "Order Number" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-table.php:19 +#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-table.php:15 msgid "Relationship" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-table.php:22 +#: vendor/woocommerce/subscriptions-core/includes/admin/meta-boxes/views/html-related-orders-table.php:18 #: vendor/woocommerce/subscriptions-core/templates/myaccount/my-subscriptions.php:24 #: vendor/woocommerce/subscriptions-core/templates/myaccount/related-orders.php:25 #: vendor/woocommerce/subscriptions-core/templates/myaccount/related-subscriptions.php:24 @@ -3160,7 +3122,7 @@ msgid "The \"all\" value for $order_type parameter is deprecated. It was a misno msgstr "" #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscription.php:2330 -#: vendor/woocommerce/subscriptions-core/wcs-functions.php:853 +#: vendor/woocommerce/subscriptions-core/wcs-functions.php:868 msgid "Payment method meta must be an array." msgstr "" @@ -3381,7 +3343,7 @@ msgstr "" #: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-change-payment-gateway.php:229 #: vendor/woocommerce/subscriptions-core/includes/class-wcs-template-loader.php:103 -#: vendor/woocommerce/subscriptions-core/includes/wcs-helper-functions.php:286 +#: vendor/woocommerce/subscriptions-core/includes/wcs-helper-functions.php:301 msgid "Invalid Subscription." msgstr "" @@ -3642,44 +3604,44 @@ msgstr "" msgid "Discount" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:244 +#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:247 msgid "Send trial is ending notification" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:248 +#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:251 msgid "Send upcoming subscription expiration notification" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:252 +#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:255 msgid "Send upcoming renewal notification" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:268 +#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:271 msgid "Customer Notifications" msgstr "" #. translators: Link to WC Settings > Email. -#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:272 +#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:275 msgid "To enable/disable individual notifications and customize templates, visit the Email settings." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:275 +#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:278 msgid "Enable Reminders" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:276 +#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:279 msgid "Send notification emails to customers for subscription renewals and expirations." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:285 +#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:288 msgid "Reminder Timing" msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:286 +#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:289 msgid "How long before the event should the notification be sent." msgstr "" -#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:291 +#: vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-email-notifications.php:294 #: vendor/woocommerce/subscriptions-core/includes/emails/class-wcs-email-customer-notification.php:60 #: vendor/woocommerce/subscriptions-core/includes/privacy/class-wcs-privacy.php:281 msgid "N/A" @@ -6361,7 +6323,7 @@ msgid "MM" msgstr "" #. translators: 1) passed sort order type argument, 2) 'ascending', 3) 'descending'. -#: vendor/woocommerce/subscriptions-core/includes/wcs-helper-functions.php:266 +#: vendor/woocommerce/subscriptions-core/includes/wcs-helper-functions.php:281 msgid "Invalid sort order type: %1$s. The $sort_order argument must be %2$s or %3$s." msgstr "" @@ -6520,6 +6482,12 @@ msgstr "" msgid "Subscription Price (%s)" msgstr "" +#: vendor/woocommerce/subscriptions-core/templates/admin/deprecated/html-variation-price.php:31 +#: vendor/woocommerce/subscriptions-core/templates/admin/deprecated/html-variation-price.php:86 +msgctxt "example price" +msgid "e.g. 9.90" +msgstr "" + #: vendor/woocommerce/subscriptions-core/templates/admin/deprecated/html-variation-price.php:46 msgid "Subscription Periods" msgstr "" @@ -6549,7 +6517,7 @@ msgstr "" #. translators: placeholder is trial period validation message if passed an invalid value (e.g. "Trial period can not exceed 4 weeks") #: vendor/woocommerce/subscriptions-core/templates/admin/deprecated/html-variation-price.php:118 -#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:27 +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:72 msgctxt "Trial period dropdown's description in pricing fields" msgid "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" msgstr "" @@ -6610,23 +6578,28 @@ msgstr[1] "" msgid "To see further details about these errors, view the %1$s log file from the %2$sWooCommerce logs screen.%2$s" msgstr "" -#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:31 -msgid "Subscription trial period:" -msgstr "" - -#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:49 +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:32 msgid "Billing interval:" msgstr "" -#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:56 +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:39 msgid "Billing Period:" msgstr "" -#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:67 +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:51 msgctxt "Subscription Length dropdown's description in pricing fields" msgid "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." msgstr "" +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:66 +msgctxt "example price" +msgid "e.g." +msgstr "" + +#: vendor/woocommerce/subscriptions-core/templates/admin/html-variation-price.php:78 +msgid "Subscription trial period:" +msgstr "" + #: vendor/woocommerce/subscriptions-core/templates/cart/cart-recurring-shipping.php:32 msgid "Shipping costs will be calculated once you have provided your address." msgstr "" @@ -6770,6 +6743,14 @@ msgctxt "table headings in notification email" msgid "Price" msgstr "" +#: vendor/woocommerce/subscriptions-core/templates/emails/cancelled-subscription.php:41 +#: vendor/woocommerce/subscriptions-core/templates/emails/expired-subscription.php:26 +#: vendor/woocommerce/subscriptions-core/templates/emails/on-hold-subscription.php:26 +#: vendor/woocommerce/subscriptions-core/wcs-functions.php:293 +msgctxt "table heading" +msgid "Last Order Date" +msgstr "" + #: vendor/woocommerce/subscriptions-core/templates/emails/cancelled-subscription.php:42 msgctxt "table headings in notification email" msgid "End of Prepaid Term" @@ -7192,6 +7173,12 @@ msgstr "" msgid "View subscription number %s" msgstr "" +#: vendor/woocommerce/subscriptions-core/templates/myaccount/my-subscriptions.php:43 +#: vendor/woocommerce/subscriptions-core/wcs-functions.php:292 +msgctxt "table heading" +msgid "Next Payment" +msgstr "" + #: vendor/woocommerce/subscriptions-core/templates/myaccount/my-subscriptions.php:49 #: vendor/woocommerce/subscriptions-core/templates/myaccount/related-orders.php:54 #: vendor/woocommerce/subscriptions-core/templates/myaccount/related-subscriptions.php:43 @@ -7381,6 +7368,26 @@ msgstr "" msgid "Can not get address type display name. Address type is not a string." msgstr "" +#: vendor/woocommerce/subscriptions-core/wcs-functions.php:290 +msgctxt "table heading" +msgid "Start Date" +msgstr "" + +#: vendor/woocommerce/subscriptions-core/wcs-functions.php:291 +msgctxt "table heading" +msgid "Trial End" +msgstr "" + +#: vendor/woocommerce/subscriptions-core/wcs-functions.php:294 +msgctxt "table heading" +msgid "Cancelled Date" +msgstr "" + +#: vendor/woocommerce/subscriptions-core/wcs-functions.php:295 +msgctxt "table heading" +msgid "End Date" +msgstr "" + #: vendor/woocommerce/subscriptions-core/wcs-functions.php:330 msgid "Date type is not a string." msgstr "" diff --git a/vendor/autoload.php b/vendor/autoload.php index e8b0da4..1277e72 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) { require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInitdf568b8a1948145d8f675fb08a939b09::getLoader(); +return ComposerAutoloaderInit99add140caccae6adfad678f070ccf26::getLoader(); diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 51e734a..07b32ed 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -322,6 +322,7 @@ class InstalledVersions } $installed = array(); + $copiedLocalDir = false; if (self::$canGetVendors) { foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { @@ -330,9 +331,11 @@ class InstalledVersions } 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} $required */ $required = require $vendorDir.'/composer/installed.php'; - $installed[] = self::$installedByVendor[$vendorDir] = $required; - if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { - self::$installed = $installed[count($installed) - 1]; + self::$installedByVendor[$vendorDir] = $required; + $installed[] = $required; + 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; } diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index ae3920b..e78f7ae 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitdf568b8a1948145d8f675fb08a939b09 +class ComposerAutoloaderInit99add140caccae6adfad678f070ccf26 { private static $loader; @@ -24,12 +24,12 @@ class ComposerAutoloaderInitdf568b8a1948145d8f675fb08a939b09 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__)); - spl_autoload_unregister(array('ComposerAutoloaderInitdf568b8a1948145d8f675fb08a939b09', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit99add140caccae6adfad678f070ccf26', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInitdf568b8a1948145d8f675fb08a939b09::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit99add140caccae6adfad678f070ccf26::getInitializer($loader)); $loader->register(true); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 5d6bf02..87af294 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInitdf568b8a1948145d8f675fb08a939b09 +class ComposerStaticInit99add140caccae6adfad678f070ccf26 { public static $prefixLengthsPsr4 = array ( 'C' => @@ -126,9 +126,9 @@ class ComposerStaticInitdf568b8a1948145d8f675fb08a939b09 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInitdf568b8a1948145d8f675fb08a939b09::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitdf568b8a1948145d8f675fb08a939b09::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInitdf568b8a1948145d8f675fb08a939b09::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit99add140caccae6adfad678f070ccf26::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit99add140caccae6adfad678f070ccf26::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit99add140caccae6adfad678f070ccf26::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index eff66a1..b62c482 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -151,17 +151,17 @@ }, { "name": "woocommerce/subscriptions-core", - "version": "8.1.1", - "version_normalized": "8.1.1.0", + "version": "8.2.0", + "version_normalized": "8.2.0.0", "source": { "type": "git", "url": "https://github.com/Automattic/woocommerce-subscriptions-core.git", - "reference": "fb74303f96c53800aaec99a27e376aa9ece968cd" + "reference": "442d585955ab048673c765a8afca680b1ea38e07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Automattic/woocommerce-subscriptions-core/zipball/fb74303f96c53800aaec99a27e376aa9ece968cd", - "reference": "fb74303f96c53800aaec99a27e376aa9ece968cd", + "url": "https://api.github.com/repos/Automattic/woocommerce-subscriptions-core/zipball/442d585955ab048673c765a8afca680b1ea38e07", + "reference": "442d585955ab048673c765a8afca680b1ea38e07", "shasum": "" }, "require": { @@ -174,7 +174,7 @@ "woocommerce/woocommerce-sniffs": "0.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", "extra": { "phpcodesniffer-search-depth": 2 @@ -204,7 +204,7 @@ "description": "Sell products and services with recurring payments in your WooCommerce Store.", "homepage": "https://github.com/Automattic/woocommerce-subscriptions-core", "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" }, "install-path": "../woocommerce/subscriptions-core" diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 2b4de89..aabd098 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,9 +1,9 @@ array( 'name' => 'woocommerce/woocommerce-subscriptions', - 'pretty_version' => 'dev-release/7.3.1', - 'version' => 'dev-release/7.3.1', - 'reference' => 'bbd68f5de02c5b7fe412d87e548a957d7bfb8abf', + 'pretty_version' => 'dev-release/7.4.0', + 'version' => 'dev-release/7.4.0', + 'reference' => 'f038fe29017b9110f7f39251b9c042a8c076125a', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -20,18 +20,18 @@ 'dev_requirement' => false, ), 'woocommerce/subscriptions-core' => array( - 'pretty_version' => '8.1.1', - 'version' => '8.1.1.0', - 'reference' => 'fb74303f96c53800aaec99a27e376aa9ece968cd', + 'pretty_version' => '8.2.0', + 'version' => '8.2.0.0', + 'reference' => '442d585955ab048673c765a8afca680b1ea38e07', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../woocommerce/subscriptions-core', 'aliases' => array(), 'dev_requirement' => false, ), 'woocommerce/woocommerce-subscriptions' => array( - 'pretty_version' => 'dev-release/7.3.1', - 'version' => 'dev-release/7.3.1', - 'reference' => 'bbd68f5de02c5b7fe412d87e548a957d7bfb8abf', + 'pretty_version' => 'dev-release/7.4.0', + 'version' => 'dev-release/7.4.0', + 'reference' => 'f038fe29017b9110f7f39251b9c042a8c076125a', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/vendor/woocommerce/subscriptions-core/assets/css/admin.css b/vendor/woocommerce/subscriptions-core/assets/css/admin.css index c5da627..73be899 100644 --- a/vendor/woocommerce/subscriptions-core/assets/css/admin.css +++ b/vendor/woocommerce/subscriptions-core/assets/css/admin.css @@ -430,9 +430,14 @@ a.close-subscriptions-search { max-width: 34%; 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; } +#variable_product_options + .variable_subscription_pricing_2_3 + p._subscription_price_field { + margin-bottom: 0; +} #variable_product_options .variable_subscription_pricing_2_3 .wc_input_subscription_trial_period + .select2, @@ -460,6 +465,11 @@ a.close-subscriptions-search { .wc_input_subscription_payment_sync_month { max-width: 86%; } +#variable_product_options + .variable_subscription_pricing_2_3 .multiple_fields .wrap { + display: flex; + gap: 12px; +} @media screen and ( max-width: 1190px ) { #variable_product_options .variable_subscription_pricing_2_3 @@ -473,7 +483,6 @@ a.close-subscriptions-search { .variable_subscription_pricing_2_3 p._subscription_price_field { width: 100%; - margin-bottom: 0; } #variable_product_options .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 { margin: 0 8px 0 2px; } +.show_if_subscription .select2-selection, .show_if_variable-subscription .select2-selection { + font-size: 14px; +} diff --git a/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css b/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css index 9154b1a..e378e85 100644 --- a/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css +++ b/vendor/woocommerce/subscriptions-core/assets/css/view-subscription.css @@ -1,6 +1,9 @@ @media only screen and ( max-width: 768px ) { .subscription_details .button { + box-sizing: border-box; margin-bottom: 2px; + padding-left: 0.5rem; + padding-right: 0.5rem; width: 100%; max-width: 200px; text-align: center; diff --git a/vendor/woocommerce/subscriptions-core/assets/js/admin/admin.js b/vendor/woocommerce/subscriptions-core/assets/js/admin/admin.js index 9b9fea1..c829045 100644 --- a/vendor/woocommerce/subscriptions-core/assets/js/admin/admin.js +++ b/vendor/woocommerce/subscriptions-core/assets/js/admin/admin.js @@ -396,7 +396,7 @@ jQuery( function ( $ ) { // Add the subscription price fields above the standard price fields $( this ).insertBefore( $regularPriceRow ); - $trialSignUpRow.insertBefore( $( this ) ); + $trialSignUpRow.insertAfter( $( this ) ); // Replace the regular price field with the trial period field $regularPriceRow diff --git a/vendor/woocommerce/subscriptions-core/changelog.txt b/vendor/woocommerce/subscriptions-core/changelog.txt index 8f95af3..7c5c0d0 100644 --- a/vendor/woocommerce/subscriptions-core/changelog.txt +++ b/vendor/woocommerce/subscriptions-core/changelog.txt @@ -1,7 +1,14 @@ *** 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 = -* 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 = * 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 - 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). +* Add - Hooks to add more columns to the Related Orders table on admin = 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. diff --git a/vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php b/vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php index 28ab32b..3dfae2e 100644 --- a/vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php +++ b/vendor/woocommerce/subscriptions-core/includes/admin/class-wc-subscriptions-admin.php @@ -316,7 +316,8 @@ class WC_Subscriptions_Admin { ?> - + + -

-

- - - - - -

- + diff --git a/vendor/woocommerce/subscriptions-core/wcs-functions.php b/vendor/woocommerce/subscriptions-core/wcs-functions.php index 7d2a709..2a597dd 100644 --- a/vendor/woocommerce/subscriptions-core/wcs-functions.php +++ b/vendor/woocommerce/subscriptions-core/wcs-functions.php @@ -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. * - * @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 { * 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 $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 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 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 $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 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 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 $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 $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 $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 $order_id To restrict subscriptions to those which have a certain parent order ID. Default 0 - No parent order restriction. + * @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. */ function wcs_get_subscriptions( $args ) { - $args = wp_parse_args( - $args, - array( - 'subscriptions_per_page' => 10, - 'paged' => 1, - 'offset' => 0, - 'orderby' => 'start_date', - 'order' => 'DESC', - 'customer_id' => 0, - 'product_id' => 0, - 'variation_id' => 0, - 'order_id' => 0, - 'subscription_status' => array( 'any' ), - 'meta_query_relation' => 'AND', - ) + $default_args = array( + 'subscriptions_per_page' => 10, + 'paged' => 1, + 'offset' => 0, + 'orderby' => 'start_date', + 'order' => 'DESC', + 'customer_id' => 0, + 'product_id' => 0, + 'variation_id' => 0, + 'order_id' => 0, + '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 ( 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(); } - // Ensure subscription_status is an array. - $args['subscription_status'] = $args['subscription_status'] ? (array) $args['subscription_status'] : []; + // Support the direct use of '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. $builtin = get_post_stati( [ '_builtin' => true ] ); @@ -444,7 +452,7 @@ function wcs_get_subscriptions( $args ) { $builtin['any'] = 'any'; // Make sure statuses start with 'wc-'. - foreach ( $args['subscription_status'] as &$status ) { + foreach ( $working_args['subscription_status'] as &$status ) { if ( isset( $builtin[ $status ] ) ) { continue; } @@ -455,23 +463,25 @@ function wcs_get_subscriptions( $args ) { // Prepare the args for WC_Order_Query. $query_args = array( 'type' => 'shop_subscription', - 'status' => $args['subscription_status'], - 'limit' => $args['subscriptions_per_page'], - 'page' => $args['paged'], - 'offset' => $args['offset'] > 0 ? $args['offset'] : null, - 'order' => $args['order'], + 'status' => $working_args['subscription_status'], + 'limit' => $working_args['limit'] ?? $working_args['subscriptions_per_page'], + 'offset' => $working_args['offset'] > 0 ? $working_args['offset'] : null, + 'order' => $working_args['order'], 'return' => 'ids', // 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 - if ( 0 !== $args['order_id'] && is_numeric( $args['order_id'] ) ) { - $query_args['parent'] = $args['order_id']; + if ( 0 !== $working_args['order_id'] && is_numeric( $working_args['order_id'] ) ) { + $query_args['parent'] = $working_args['order_id']; } // Map subscription specific orderby values to internal keys. - switch ( $args['orderby'] ) { + switch ( $working_args['orderby'] ) { case 'status': wcs_deprecated_argument( __FUNCTION__, 'subscriptions-core 5.0.0', 'The "status" orderby value is deprecated.' ); break; @@ -481,8 +491,8 @@ function wcs_get_subscriptions( $args ) { case 'trial_end_date': case 'end_date': // We need to orderby post meta value: http://www.paulund.co.uk/order-meta-query - $date_type = str_replace( '_date', '', $args['orderby'] ); - $query_args = array_merge( $query_args, array( + $date_type = str_replace( '_date', '', $working_args['orderby'] ); + $query_args = array_merge( $query_args, array( 'orderby' => 'meta_value', 'meta_key' => wcs_get_date_meta_key( $date_type ), 'meta_type' => 'DATETIME', @@ -494,51 +504,56 @@ function wcs_get_subscriptions( $args ) { ); break; default: - $query_args['orderby'] = $args['orderby']; + $query_args['orderby'] = $working_args['orderby']; break; } // 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. 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 ); } 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. // 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. - $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. if ( $query_controller->has_product_query() ) { 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. - 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. $query_args['limit'] = -1; } 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 ); } } 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(). * * @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(); 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 ); } - return apply_filters( 'woocommerce_got_subscriptions', $subscriptions, $args ); + return apply_filters( 'woocommerce_got_subscriptions', $subscriptions, $working_args ); } /** diff --git a/vendor/woocommerce/subscriptions-core/woocommerce-subscriptions-core.php b/vendor/woocommerce/subscriptions-core/woocommerce-subscriptions-core.php index 7e722ce..bb726a6 100644 --- a/vendor/woocommerce/subscriptions-core/woocommerce-subscriptions-core.php +++ b/vendor/woocommerce/subscriptions-core/woocommerce-subscriptions-core.php @@ -6,5 +6,5 @@ * Author: Automattic * Author URI: https://woocommerce.com/ * Requires WP: 5.6 - * Version: 8.1.1 + * Version: 8.2.0 */ diff --git a/woocommerce-subscriptions.php b/woocommerce-subscriptions.php index 4653448..d415c2a 100644 --- a/woocommerce-subscriptions.php +++ b/woocommerce-subscriptions.php @@ -5,7 +5,7 @@ * Description: Sell products and services with recurring payments in your WooCommerce Store. * Author: WooCommerce * Author URI: https://woocommerce.com/ - * Version: 7.3.1 + * Version: 7.4.0 * Requires Plugins: woocommerce * * WC requires at least: 8.7.1 @@ -78,7 +78,7 @@ class WC_Subscriptions { public static $plugin_file = __FILE__; /** @var string */ - public static $version = '7.3.1'; // WRCS: DEFINED_VERSION. + public static $version = '7.4.0'; // WRCS: DEFINED_VERSION. /** @var string */ public static $wc_minimum_supported_version = '7.7'; @@ -149,7 +149,7 @@ class WC_Subscriptions { $trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 1 ); $file = $trace[0]['file']; $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 } } }