diff --git a/includes/class-wc-tracker.php b/includes/class-wc-tracker.php index 9b009e035ea..582a2210d19 100644 --- a/includes/class-wc-tracker.php +++ b/includes/class-wc-tracker.php @@ -355,122 +355,170 @@ class WC_Tracker { } /** - * Get all order data. + * Get order counts. + * + * @return array + */ + private static function get_order_counts() { + $order_count = array(); + $order_count_data = wp_count_posts( 'shop_order' ); + foreach ( wc_get_order_statuses() as $status_slug => $status_name ) { + $order_count[ $status_slug ] = $order_count_data->{ $status_slug }; + } + return $order_count; + } + + /** + * Combine all order data. * * @return array */ private static function get_orders() { - $args = array( - 'type' => array( 'shop_order', 'shop_order_refund' ), - 'limit' => get_option( 'posts_per_page' ), - 'paged' => 1, + $order_dates = self::get_order_dates(); + $order_counts = self::get_order_counts(); + $order_totals = self::get_order_totals(); + $order_gateways = self::get_orders_by_gateway(); + + return array_merge( $order_dates, $order_counts, $order_totals, $order_gateways ); + } + + /** + * Get order totals. + * + * @since 5.4.0 + * @return array + */ + private static function get_order_totals() { + global $wpdb; + + $gross_total = $wpdb->get_var( + " + SELECT + SUM( order_meta.meta_value ) AS 'gross_total' + FROM {$wpdb->prefix}posts AS orders + LEFT JOIN {$wpdb->prefix}postmeta AS order_meta ON order_meta.post_id = orders.ID + WHERE order_meta.meta_key = '_order_total' + AND orders.post_status in ( 'wc-completed', 'wc-refunded' ) + GROUP BY order_meta.meta_key + " ); - $first = time(); - $processing_first = $first; - $first_time = $first; - $last = 0; - $processing_last = 0; - $order_data = array(); - - $orders = wc_get_orders( $args ); - $orders_count = count( $orders ); - - while ( $orders_count ) { - - foreach ( $orders as $order ) { - - $date_created = (int) $order->get_date_created()->getTimestamp(); - $type = $order->get_type(); - $status = $order->get_status(); - - if ( 'shop_order' == $type ) { - - // Find the first and last order dates for completed and processing statuses. - if ( 'completed' == $status && $date_created < $first ) { - $first = $date_created; - } - if ( 'completed' == $status && $date_created > $last ) { - $last = $date_created; - } - if ( 'processing' == $status && $date_created < $processing_first ) { - $processing_first = $date_created; - } - if ( 'processing' == $status && $date_created > $processing_last ) { - $processing_last = $date_created; - } - - // Get order counts by status. - $status = 'wc-' . $status; - - if ( ! isset( $order_data[ $status ] ) ) { - $order_data[ $status ] = 1; - } else { - $order_data[ $status ] += 1; - } - - // Count number of orders by gateway used. - $gateway = $order->get_payment_method(); - - if ( ! empty( $gateway ) && in_array( $status, array( 'wc-completed', 'wc-refunded', 'wc-processing' ) ) ) { - $gateway = 'gateway_' . $gateway; - - if ( ! isset( $order_data[ $gateway ] ) ) { - $order_data[ $gateway ] = 1; - } else { - $order_data[ $gateway ] += 1; - } - } - } else { - // If it is a refunded order (shop_order_refunnd type), add the prefix as this prefix gets - // added midway in the if clause. - $status = 'wc-' . $status; - } - - // Calculate the gross total for 'completed' and 'processing' orders. - $total = $order->get_total(); - - if ( in_array( $status, array( 'wc-completed', 'wc-refunded' ) ) ) { - if ( ! isset( $order_data['gross'] ) ) { - $order_data['gross'] = $total; - } else { - $order_data['gross'] += $total; - } - } elseif ( 'wc-processing' == $status ) { - if ( ! isset( $order_data['processing_gross'] ) ) { - $order_data['processing_gross'] = $total; - } else { - $order_data['processing_gross'] += $total; - } - } - } - $args['paged']++; - - $orders = wc_get_orders( $args ); - $orders_count = count( $orders ); + if ( is_null( $gross_total ) ) { + $gross_total = 0; } - if ( $first !== $first_time ) { - $order_data['first'] = gmdate( 'Y-m-d H:i:s', $first ); + $processing_gross_total = $wpdb->get_var( + " + SELECT + SUM( order_meta.meta_value ) AS 'gross_total' + FROM {$wpdb->prefix}posts AS orders + LEFT JOIN {$wpdb->prefix}postmeta AS order_meta ON order_meta.post_id = orders.ID + WHERE order_meta.meta_key = '_order_total' + AND orders.post_status = 'wc-processing' + GROUP BY order_meta.meta_key + " + ); + + if ( is_null( $processing_gross_total ) ) { + $processing_gross_total = 0; } - if ( $processing_first !== $first_time ) { - $order_data['processing_first'] = gmdate( 'Y-m-d H:i:s', $processing_first ); + return array( + 'gross' => $gross_total, + 'processing_gross' => $processing_gross_total, + ); + } + + /** + * Get last order date. + * + * @return string + */ + private static function get_order_dates() { + global $wpdb; + + $min_max = $wpdb->get_row( + " + SELECT + MIN( post_date_gmt ) as 'first', MAX( post_date_gmt ) as 'last' + FROM {$wpdb->prefix}posts + WHERE post_type = 'shop_order' + AND post_status = 'wc-completed' + ", + ARRAY_A + ); + + if ( is_null( $min_max ) ) { + $min_max = array( + 'first' => '-', + 'last' => '-', + ); } - if ( $last ) { - $order_data['last'] = gmdate( 'Y-m-d H:i:s', $last ); + $processing_min_max = $wpdb->get_row( + " + SELECT + MIN( post_date_gmt ) as 'processing_first', MAX( post_date_gmt ) as 'processing_last' + FROM {$wpdb->prefix}posts + WHERE post_type = 'shop_order' + AND post_status = 'wc-processing' + ", + ARRAY_A + ); + + if ( is_null( $processing_min_max ) ) { + $processing_min_max = array( + 'processing_first' => '-', + 'processing_last' => '-', + ); } - if ( $processing_last ) { - $order_data['processing_last'] = gmdate( 'Y-m-d H:i:s', $processing_last ); + return array_merge( $min_max, $processing_min_max ); + } + + /** + * Get order details by gateway. + * + * @return array + */ + private static function get_orders_by_gateway() { + global $wpdb; + + $orders_by_gateway = $wpdb->get_results( + " + SELECT + gateway, currency, SUM(total) AS totals, COUNT(order_id) AS counts + FROM ( + SELECT + orders.id AS order_id, + MAX(CASE WHEN meta_key = '_payment_method' THEN meta_value END) gateway, + MAX(CASE WHEN meta_key = '_order_total' THEN meta_value END) total, + MAX(CASE WHEN meta_key = '_order_currency' THEN meta_value END) currency + FROM + {$wpdb->prefix}posts orders + LEFT JOIN + {$wpdb->prefix}postmeta order_meta ON order_meta.post_id = orders.id + WHERE orders.post_type = 'shop_order' + AND orders.post_status in ( 'wc-completed', 'wc-processing', 'wc-refunded' ) + AND meta_key in( '_payment_method','_order_total','_order_currency') + GROUP BY orders.id + ) order_gateways + GROUP BY gateway, currency + " + ); + + $orders_by_gateway_currency = array(); + foreach ( $orders_by_gateway as $orders_details ) { + $gateway = 'gateway_' . $orders_details->gateway; + $currency = $orders_details->currency; + $count = $gateway . '_' . $currency . '_count'; + $total = $gateway . '_' . $currency . '_total'; + + $orders_by_gateway_currency[ $count ] = $orders_details->counts; + $orders_by_gateway_currency[ $total ] = $orders_details->totals; } - foreach ( $order_data as $key => $value ) { - $order_data[ $key ] = (string) $value; - } - - return $order_data; + return $orders_by_gateway_currency; } /** @@ -635,17 +683,6 @@ class WC_Tracker { return array_filter( (array) get_option( 'woocommerce_tracker_ua', array() ) ); } - /** - * Get order totals - * - * @deprecated 5.1.0 Logic moved to get_orders. - * @return array - */ - public static function get_order_totals() { - wc_deprecated_function( 'WC_Tracker::get_order_totals', '5.1.0', '' ); - return self::get_orders(); - } - /** * Search a specific post for text content. *