generating_report, array( 'new_subscriptions', 'renewals', 'resubscribes', 'switches' ) ) ) { $this->report_data->{$this->generating_report . '_query_hash'} = md5( 'get_results' . implode( ' ', $query ) ); } return $query; } /** * Get report data * @return array */ public function get_report_data() { if ( empty( $this->report_data ) ) { $this->get_data(); } return $this->report_data; } /** * Get all data needed for this report and store in the class */ public function get_data( $args = array() ) { global $wpdb; $update_cache = false; $default_args = array( 'no_cache' => false, 'order_status' => apply_filters( 'woocommerce_reports_order_statuses', array( 'completed', 'processing', 'on-hold' ) ), ); $args = apply_filters( 'wcs_reports_subscription_events_args', $args ); $args = wp_parse_args( $args, $default_args ); $query_end_date = date( 'Y-m-d', strtotime( '+1 DAY', $this->end_date ) ); $offset = get_option( 'gmt_offset' ); // Convert from Decimal format(eg. 11.5) to a suitable format(eg. +11:30) for CONVERT_TZ() of SQL query. $site_timezone = sprintf( '%+02d:%02d', (int) $offset, ( $offset - floor( $offset ) ) * 60 ); $this->report_data = new stdClass; // While generating report data via get_order_report_data(), hook in to set the query hash so we can cache the results. add_filter( 'woocommerce_reports_get_order_report_query', array( $this, 'set_query_hash' ) ); $this->generating_report = 'new_subscriptions'; $this->report_data->new_subscriptions_data = (array) $this->get_order_report_data( array( 'data' => array( 'ID' => array( 'type' => 'post_data', 'function' => 'COUNT', 'name' => 'count', 'distinct' => true, ), 'id' => array( 'type' => 'post_data', 'function' => 'GROUP_CONCAT', 'name' => 'subscription_ids', 'distinct' => true, ), 'post_date' => array( 'type' => 'post_data', 'function' => '', 'name' => 'post_date', ), ), 'where' => array( 'post_status' => array( 'key' => 'post_status', 'operator' => 'NOT IN', 'value' => array( 'trash', 'auto-draft' ), ), ), 'group_by' => $this->group_by_query, 'order_status' => array(), 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => array( 'shop_subscription' ), 'nocache' => $args['no_cache'], ) ); $this->generating_report = 'renewals'; $this->report_data->renewal_data = (array) $this->get_order_report_data( array( 'data' => array( 'ID' => array( 'type' => 'post_data', 'function' => 'COUNT', 'name' => 'count', 'distinct' => true, ), 'id' => array( 'type' => 'post_data', 'function' => 'GROUP_CONCAT', 'name' => 'order_ids', 'distinct' => true, ), 'post_date' => array( 'type' => 'post_data', 'function' => '', 'name' => 'post_date', ), '_subscription_renewal' => array( 'type' => 'meta', 'function' => '', 'name' => 'renewal_orders', ), '_order_total' => array( 'type' => 'meta', 'function' => 'SUM', 'name' => 'renewal_totals', 'join_type' => 'LEFT', // To avoid issues if there is no renewal_total meta ), ), 'where' => array( 'post_status' => array( 'key' => 'post_status', 'operator' => 'NOT IN', 'value' => array( 'trash', 'auto-draft' ), ), ), 'group_by' => $this->group_by_query, 'order_status' => $args['order_status'], 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types( 'order-count' ), 'nocache' => $args['no_cache'], ) ); $this->generating_report = 'resubscribes'; $this->report_data->resubscribe_data = (array) $this->get_order_report_data( array( 'data' => array( 'ID' => array( 'type' => 'post_data', 'function' => 'COUNT', 'name' => 'count', 'distinct' => true, ), 'id' => array( 'type' => 'post_data', 'function' => 'GROUP_CONCAT', 'name' => 'order_ids', 'distinct' => true, ), 'post_date' => array( 'type' => 'post_data', 'function' => '', 'name' => 'post_date', ), '_subscription_resubscribe' => array( 'type' => 'meta', 'function' => '', 'name' => 'resubscribe_orders', ), '_order_total' => array( 'type' => 'meta', 'function' => 'SUM', 'name' => 'resubscribe_totals', 'join_type' => 'LEFT', // To avoid issues if there is no resubscribe_total meta ), ), 'where' => array( 'post_status' => array( 'key' => 'post_status', 'operator' => 'NOT IN', 'value' => array( 'trash', 'auto-draft' ), ), ), 'group_by' => $this->group_by_query, 'order_status' => $args['order_status'], 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types( 'order-count' ), 'nocache' => $args['no_cache'], ) ); $this->generating_report = 'switches'; $this->report_data->switch_data = (array) $this->get_order_report_data( array( 'data' => array( 'ID' => array( 'type' => 'post_data', 'function' => 'COUNT', 'name' => 'count', 'distinct' => true, ), 'id' => array( 'type' => 'post_data', 'function' => 'GROUP_CONCAT', 'name' => 'order_ids', 'distinct' => true, ), 'post_date' => array( 'type' => 'post_data', 'function' => '', 'name' => 'post_date', ), '_subscription_switch' => array( 'type' => 'meta', 'function' => '', 'name' => 'switch_orders', ), '_order_total' => array( 'type' => 'meta', 'function' => 'SUM', 'name' => 'switch_totals', 'join_type' => 'LEFT', // To avoid issues if there is no switch_total meta ), ), 'where' => array( 'post_status' => array( 'key' => 'post_status', 'operator' => 'NOT IN', 'value' => array( 'trash', 'auto-draft' ), ), ), 'group_by' => $this->group_by_query, 'order_status' => $args['order_status'], 'order_by' => 'post_date ASC', 'query_type' => 'get_results', 'filter_range' => true, 'order_types' => wc_get_order_types( 'order-count' ), 'nocache' => $args['no_cache'], ) ); // We've finished generating report data via get_order_report_data() so unhook our query hash flagging function. unset( $this->generating_report ); remove_filter( 'woocommerce_reports_get_order_report_query', array( $this, 'set_query_hash' ) ); $cached_results = get_transient( strtolower( get_class( $this ) ) ); // Set a default value for cached results for PHP 8.2+ compatibility. if ( empty( $cached_results ) ) { $cached_results = []; } // Check if we need to update the cache with the query results from the figures generated by get_order_report_data(). foreach ( array( 'new_subscriptions' => 'new_subscriptions', 'renewals' => 'renewal', 'resubscribes' => 'resubscribe', 'switches' => 'switch' ) as $report => $property_key ) { // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound $query_hash = $this->report_data->{"{$report}_query_hash"}; if ( ! isset( $cached_results[ $query_hash ] ) ) { $cached_results[ $query_hash ] = $this->report_data->{"{$property_key}_data"}; $update_cache = true; } } /* * New subscription orders */ $query = $wpdb->prepare( "SELECT SUM(subscriptions.count) as count, order_posts.post_date as post_date, SUM(order_total_post_meta.meta_value) as signup_totals, GROUP_CONCAT( DISTINCT subscriptions.ids ) as subscription_ids FROM {$wpdb->posts} AS order_posts INNER JOIN ( SELECT COUNT(DISTINCT(subscription_posts.ID)) as count, subscription_posts.post_parent as order_id, GROUP_CONCAT( subscription_posts.ID ) as ids FROM {$wpdb->posts} as subscription_posts WHERE subscription_posts.post_type = 'shop_subscription' AND subscription_posts.post_date >= %s AND subscription_posts.post_date < %s AND subscription_posts.post_status NOT IN ( 'trash', 'auto-draft' ) GROUP BY order_id ) 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'] ) . "' ) 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 ); $query_hash = md5( $query ); if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { $wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' ); $cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_sign_up_data', (array) $wpdb->get_results( $query ), $args ); $update_cache = true; } $this->report_data->signup_data = $cached_results[ $query_hash ]; $this->report_data->signup_orders_query_hash = $query_hash; /* * Subscribers by date */ $query = $wpdb->prepare( "SELECT searchdate.Date as date, COUNT( DISTINCT wcsubs.ID) as count, GROUP_CONCAT( DISTINCT wcsubs.ID ) as subscription_ids FROM ( SELECT DATE(last_thousand_days.Date) as Date FROM ( SELECT DATE(%s) - INTERVAL(units.digit + (10 * tens.digit) + (100 * hundreds.digit)) DAY as Date FROM ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) as units CROSS JOIN ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) as tens CROSS JOIN ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) AS hundreds ) last_thousand_days WHERE last_thousand_days.Date >= %s AND last_thousand_days.Date <= %s ) searchdate, {$wpdb->posts} AS wcsubs, {$wpdb->postmeta} AS wcsmeta WHERE wcsubs.ID = wcsmeta.post_id AND wcsmeta.meta_key = '%s' AND DATE( wcsubs.post_date ) <= searchdate.Date AND wcsubs.post_type IN ( 'shop_subscription' ) AND wcsubs.post_status NOT IN( 'auto-draft' ) AND ( DATE( CONVERT_TZ( wcsmeta.meta_value , '+00:00', %s ) ) >= searchdate.Date OR wcsmeta.meta_value = 0 OR wcsmeta.meta_value IS NULL ) GROUP BY searchdate.Date ORDER BY searchdate.Date ASC", $query_end_date, date( 'Y-m-d', $this->start_date ), $query_end_date, wcs_get_date_meta_key( 'end' ), $site_timezone ); $query_hash = md5( $query ); if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { $wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' ); $cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_subscriber_count_data', (array) $wpdb->get_results( $query ), $args ); $update_cache = true; } $this->report_data->subscriber_counts = $cached_results[ $query_hash ]; $this->report_data->current_subscriptions_query_hash = $query_hash; /* * 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 FROM {$wpdb->posts} as wcsubs JOIN {$wpdb->postmeta} AS wcsmeta_cancel ON wcsubs.ID = wcsmeta_cancel.post_id AND wcsmeta_cancel.meta_key = %s AND wcsubs.post_status NOT IN ( 'trash', 'auto-draft' ) 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", wcs_get_date_meta_key( 'cancelled' ), date( 'Y-m-d', $this->start_date ), $query_end_date ); $query_hash = md5( $query ); if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { $wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' ); $cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_cancel_count_data', (array) $wpdb->get_results( $query ), $args ); $update_cache = true; } $this->report_data->cancel_counts = $cached_results[ $query_hash ]; $this->report_data->cancelled_subscriptions_query_hash = $query_hash; /* * 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 FROM {$wpdb->posts} as wcsubs JOIN {$wpdb->postmeta} AS wcsmeta_end ON wcsubs.ID = wcsmeta_end.post_id AND wcsmeta_end.meta_key = %s AND wcsubs.post_status NOT IN ( 'trash', 'auto-draft' ) 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", wcs_get_date_meta_key( 'end' ), date( 'Y-m-d', $this->start_date ), $query_end_date ); $query_hash = md5( $query ); if ( $args['no_cache'] || ! isset( $cached_results[ $query_hash ] ) ) { $wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' ); $cached_results[ $query_hash ] = apply_filters( 'wcs_reports_subscription_events_ended_count_data', (array) $wpdb->get_results( $query ), $args ); $update_cache = true; } $this->report_data->ended_counts = $cached_results[ $query_hash ]; $this->report_data->ended_subscriptions_query_hash = $query_hash; // Total up the query data $this->report_data->signup_orders_total_amount = array_sum( wp_list_pluck( $this->report_data->signup_data, 'signup_totals' ) ); $this->report_data->renewal_orders_total_amount = array_sum( wp_list_pluck( $this->report_data->renewal_data, 'renewal_totals' ) ); $this->report_data->resubscribe_orders_total_amount = array_sum( wp_list_pluck( $this->report_data->resubscribe_data, 'resubscribe_totals' ) ); $this->report_data->switch_orders_total_amount = array_sum( wp_list_pluck( $this->report_data->switch_data, 'switch_totals' ) ); $this->report_data->new_subscription_total_count = absint( array_sum( wp_list_pluck( $this->report_data->new_subscriptions_data, 'count' ) ) ); $this->report_data->signup_orders_total_count = absint( array_sum( wp_list_pluck( $this->report_data->signup_data, 'count' ) ) ); $this->report_data->renewal_orders_total_count = absint( array_sum( wp_list_pluck( $this->report_data->renewal_data, 'count' ) ) ); $this->report_data->resubscribe_orders_total_count = absint( array_sum( wp_list_pluck( $this->report_data->resubscribe_data, 'count' ) ) ); $this->report_data->switch_orders_total_count = absint( array_sum( wp_list_pluck( $this->report_data->switch_data, 'count' ) ) ); $this->report_data->total_subscriptions_cancelled = absint( array_sum( wp_list_pluck( $this->report_data->cancel_counts, 'count' ) ) ); $this->report_data->total_subscriptions_ended = absint( array_sum( wp_list_pluck( $this->report_data->ended_counts, 'count' ) ) ); $this->report_data->total_subscriptions_at_period_end = $this->report_data->subscriber_counts ? absint( end( $this->report_data->subscriber_counts )->count ) : 0; $this->report_data->total_subscriptions_at_period_start = isset( $this->report_data->subscriber_counts[0]->count ) ? absint( $this->report_data->subscriber_counts[0]->count ) : 0; if ( $update_cache ) { set_transient( strtolower( get_class( $this ) ), $cached_results, WEEK_IN_SECONDS ); // Remove this class from the list of classes WC updates on shutdown. Introduced in WC 3.7 if ( ! wcs_is_woocommerce_pre( '3.7' ) ) { unset( WC_Admin_Report::$transients_to_update[ strtolower( get_class( $this ) ) ] ); } } } /** * Get the legend for the main chart sidebar * * @return array */ public function get_chart_legend() { $legend = array(); $data = $this->get_report_data(); $tracks_id = 'report_subscription_events_by_date_'; $legend[] = array( // translators: %s: formatted total amount. 'title' => sprintf( __( '%s signup revenue in this period', 'woocommerce-subscriptions' ), '' . wc_price( $data->signup_orders_total_amount ) . '' ), 'placeholder' => __( 'The sum of all subscription parent orders, including other items, fees, tax and shipping.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['signup_total'], 'highlight_series' => 8, ); $legend[] = array( // translators: %s: formatted total amount. 'title' => sprintf( __( '%s renewal revenue in this period', 'woocommerce-subscriptions' ), '' . wc_price( $data->renewal_orders_total_amount ) . '' ), 'placeholder' => __( 'The sum of all renewal orders including tax and shipping.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['renewal_total'], 'highlight_series' => 10, ); $legend[] = array( // translators: %s: formatted total amount. 'title' => sprintf( __( '%s resubscribe revenue in this period', 'woocommerce-subscriptions' ), '' . wc_price( $data->resubscribe_orders_total_amount ) . '' ), 'placeholder' => __( 'The sum of all resubscribe orders including tax and shipping.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['resubscribe_total'], 'highlight_series' => 9, ); $legend[] = array( // translators: %s: formatted total amount. 'title' => sprintf( __( '%s switch revenue in this period', 'woocommerce-subscriptions' ), '' . wc_price( $data->switch_orders_total_amount ) . '' ), 'placeholder' => __( 'The sum of all switch orders including tax and shipping.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['switch_total'], 'highlight_series' => 11, ); $legend[] = array( 'title' => sprintf( // translators: 2: link opening tag, 1: subscription count and closing tag. __( '%2$s %1$s new subscriptions', 'woocommerce-subscriptions' ), ' ' . $this->report_data->new_subscription_total_count . ' ', '' ), 'placeholder' => __( '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.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['new_count'], 'highlight_series' => 1, ); $legend[] = array( 'title' => sprintf( // translators: 2: link opening tag, 1: subscription count and closing tag. __( '%2$s %1$s subscription signups', 'woocommerce-subscriptions' ), ' ' . $this->report_data->signup_orders_total_count . ' ', '' ), 'placeholder' => __( '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.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['signup_count'], 'highlight_series' => 2, ); $legend[] = array( 'title' => sprintf( // translators: 2: link opening tag, 1: subscription count and closing tag. __( '%2$s %1$s subscription resubscribes', 'woocommerce-subscriptions' ), ' ' . $this->report_data->resubscribe_orders_total_count . ' ', '' ), 'placeholder' => __( 'The number of resubscribe orders processed during this period.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['resubscribe_count'], 'highlight_series' => 3, ); $legend[] = array( 'title' => sprintf( // translators: 2: link opening tag, 1: subscription count and closing tag. __( '%2$s %1$s subscription renewals', 'woocommerce-subscriptions' ), ' ' . $this->report_data->renewal_orders_total_count . ' ', '' ), 'placeholder' => __( 'The number of renewal orders processed during this period.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['renewal_count'], 'highlight_series' => 4, ); $legend[] = array( 'title' => sprintf( // translators: 2: link opening tag, 1: subscription count and closing tag. __( '%2$s %1$s subscription switches', 'woocommerce-subscriptions' ), ' ' . $this->report_data->switch_orders_total_count . ' ', '' ), 'placeholder' => __( 'The number of subscriptions upgraded, downgraded or cross-graded during this period.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['switch_count'], 'highlight_series' => 0, ); $legend[] = array( 'title' => sprintf( // translators: 2: link opening tag, 1: subscription count and closing tag. __( '%2$s %1$s subscription cancellations', 'woocommerce-subscriptions' ), ' ' . $this->report_data->total_subscriptions_cancelled . ' ', '' ), 'placeholder' => __( '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.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['cancel_count'], 'highlight_series' => 7, ); $legend[] = array( 'title' => sprintf( // translators: 2: link opening tag, 1: subscription count and closing tag. __( '%2$s %1$s ended subscriptions', 'woocommerce-subscriptions' ), ' ' . $this->report_data->total_subscriptions_ended . ' ', '' ), 'placeholder' => __( 'The number of subscriptions which have either expired or reached the end of the prepaid term if it was previously cancelled.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['ended_count'], 'highlight_series' => 6, ); // For the subscriptions count we only need to display the subscriptions included on the last day of the report period so pass the last cache key. The array keys are integers so using max() returns the last array key. $data_key = $this->report_data->subscriber_counts ? max( array_keys( $this->report_data->subscriber_counts ) ) : false; $legend[] = array( 'title' => sprintf( // translators: 2: link opening tag, 1: subscription count and closing tag. __( '%2$s %1$s current subscriptions', 'woocommerce-subscriptions' ), ' ' . $this->report_data->total_subscriptions_at_period_end . ' ', '' ), 'placeholder' => __( 'The number of subscriptions during this period with an end date in the future and a status other than pending.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['subscriber_count'], 'highlight_series' => 5, ); $subscription_change_count = ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start > 0 ) ? '+' . ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start ) : ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start ); if ( 0 === $data->total_subscriptions_at_period_start ) { $subscription_change_percent = '∞%'; // infinite percentage increase if the starting subs is 0. } elseif ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start >= 0 ) { $subscription_change_percent = '+' . number_format( ( ( ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start ) / $data->total_subscriptions_at_period_start ) * 100 ), 2 ) . '%'; } else { $subscription_change_percent = number_format( ( ( ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start ) / $data->total_subscriptions_at_period_start ) * 100 ), 2 ) . '%'; } if ( $data->total_subscriptions_at_period_end - $data->total_subscriptions_at_period_start >= 0 ) { // translators: %s: subscription net gain (with percentage). $legend_title = __( '%s net subscription gain', 'woocommerce-subscriptions' ); } else { // translators: %s: subscription net loss (with percentage). $legend_title = __( '%s net subscription loss', 'woocommerce-subscriptions' ); } $legend[] = array( 'title' => sprintf( $legend_title, '' . $subscription_change_count . ' (' . $subscription_change_percent . ')' ), 'placeholder' => __( 'Change in subscriptions between the start and end of the period.', 'woocommerce-subscriptions' ), 'color' => $this->chart_colours['subscriber_change'], 'highlight_series' => 5, ); return $legend; } /** * Output the report */ public function output_report() { $ranges = array( 'year' => __( 'Year', 'woocommerce-subscriptions' ), 'last_month' => __( 'Last Month', 'woocommerce-subscriptions' ), 'month' => __( 'This Month', 'woocommerce-subscriptions' ), '7day' => __( 'Last 7 Days', 'woocommerce-subscriptions' ), ); $this->chart_colours = array( 'signup_total' => '#439ad9', 'renewal_total' => '#b1d4ea', 'resubscribe_total' => '#7ab7e2', 'switch_total' => '#a7b7f1', 'new_count' => '#9adbb5', 'signup_count' => '#5cc488', 'resubscribe_count' => '#449163', 'renewal_count' => '#b9e6cc', 'switch_count' => '#f1c40f', 'cancel_count' => '#e74c3c', 'ended_count' => '#f8ccc7', 'subscriber_count' => '#ecf0f1', 'subscriber_change' => '#ecf0f1', ); $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) { $current_range = '7day'; } $this->calculate_current_range( $current_range ); include( WC()->plugin_path() . '/includes/admin/views/html-report-by-date.php' ); } /** * Output an export link */ public function get_export_button() { $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; ?> prepare_chart_data( $this->report_data->signup_data, 'post_date', 'signup_totals', $this->chart_interval, $this->start_date, $this->chart_groupby ); $renewal_orders_amount = $this->prepare_chart_data( $this->report_data->renewal_data, 'post_date', 'renewal_totals', $this->chart_interval, $this->start_date, $this->chart_groupby ); $resubscribe_orders_amount = $this->prepare_chart_data( $this->report_data->resubscribe_data, 'post_date', 'resubscribe_totals', $this->chart_interval, $this->start_date, $this->chart_groupby ); $switch_orders_amount = $this->prepare_chart_data( $this->report_data->switch_data, 'post_date', 'switch_totals', $this->chart_interval, $this->start_date, $this->chart_groupby ); $new_subscriptions_count = $this->prepare_chart_data( $this->report_data->new_subscriptions_data, 'post_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby ); $signup_orders_count = $this->prepare_chart_data( $this->report_data->signup_data, 'post_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby ); $renewal_orders_count = $this->prepare_chart_data( $this->report_data->renewal_data, 'post_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby ); $resubscribe_orders_count = $this->prepare_chart_data( $this->report_data->resubscribe_data, 'post_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby ); $switch_orders_count = $this->prepare_chart_data( $this->report_data->switch_data, 'post_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby ); $subscriber_count = $this->prepare_chart_data_daily_average( $this->report_data->subscriber_counts, 'date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby ); $cancel_count = $this->prepare_chart_data( $this->report_data->cancel_counts, 'cancel_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby ); $ended_count = $this->prepare_chart_data( $this->report_data->ended_counts, 'end_date', 'count', $this->chart_interval, $this->start_date, $this->chart_groupby ); // Encode in json format $chart_data = array( 'signup_orders_amount' => array_map( array( $this, 'round_chart_totals' ), array_values( $signup_orders_amount ) ), 'renewal_orders_amount' => array_map( array( $this, 'round_chart_totals' ), array_values( $renewal_orders_amount ) ), 'resubscribe_orders_amount' => array_map( array( $this, 'round_chart_totals' ), array_values( $resubscribe_orders_amount ) ), 'switch_orders_amount' => array_map( array( $this, 'round_chart_totals' ), array_values( $switch_orders_amount ) ), 'new_subscriptions_count' => array_values( $new_subscriptions_count ), 'signup_orders_count' => array_values( $signup_orders_count ), 'renewal_orders_count' => array_values( $renewal_orders_count ), 'resubscribe_orders_count' => array_values( $resubscribe_orders_count ), 'switch_orders_count' => array_values( $switch_orders_count ), 'subscriber_count' => array_values( $subscriber_count ), 'cancel_count' => array_values( $cancel_count ), 'ended_count' => array_values( $ended_count ), ); $timeformat = ( $this->chart_groupby == 'day' ? '%d %b' : '%b' ); ?>