Merge pull request #29877 from woocommerce/tracker_sql_query

Move Tracker to use direct sql queries
This commit is contained in:
Roy Ho 2021-05-12 14:53:49 -07:00 committed by GitHub
commit 4d6559e957
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 148 additions and 111 deletions

View File

@ -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.
*