Add WC Tracker unique payment method (#37951)
Co-authored-by: Corey McKrill <916023+coreymckrill@users.noreply.github.com>
This commit is contained in:
parent
1b8eeed2e2
commit
c3d06ad05f
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: update
|
||||
|
||||
In the WC Tracker, group payment methods and origins ignoring unique ids within their names.
|
|
@ -419,7 +419,7 @@ class WC_Tracker {
|
|||
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'
|
||||
WHERE order_meta.meta_key = '_order_total'
|
||||
AND orders.post_status in ( 'wc-completed', 'wc-refunded' )
|
||||
GROUP BY order_meta.meta_key
|
||||
"
|
||||
|
@ -435,7 +435,7 @@ class WC_Tracker {
|
|||
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'
|
||||
WHERE order_meta.meta_key = '_order_total'
|
||||
AND orders.post_status = 'wc-processing'
|
||||
GROUP BY order_meta.meta_key
|
||||
"
|
||||
|
@ -498,6 +498,69 @@ class WC_Tracker {
|
|||
return array_merge( $min_max, $processing_min_max );
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the group key for an associative array of objects which have unique ids in the key.
|
||||
* A 'group_key' property is introduced in the object.
|
||||
* For example, two objects with keys like 'WooDataPay ** #123' and 'WooDataPay ** #78' would
|
||||
* both have a group_key of 'WooDataPay **' after this function call.
|
||||
*
|
||||
* @param array $objects The array of objects that need to be grouped.
|
||||
* @param string $default_key The property that will be the default group_key.
|
||||
* @return array Contains the objects with a group_key property.
|
||||
*/
|
||||
private static function extract_group_key( $objects, $default_key ) {
|
||||
$keys = array_keys( $objects );
|
||||
|
||||
// Sort keys by length and then by characters within the same length keys.
|
||||
usort(
|
||||
$keys,
|
||||
function( $a, $b ) {
|
||||
if ( strlen( $a ) === strlen( $b ) ) {
|
||||
return strcmp( $a, $b );
|
||||
}
|
||||
return ( strlen( $a ) < strlen( $b ) ) ? -1 : 1;
|
||||
}
|
||||
);
|
||||
|
||||
// Look for common tokens in every pair of adjacent keys.
|
||||
$prev = '';
|
||||
foreach ( $keys as $key ) {
|
||||
if ( $prev ) {
|
||||
$comm_tokens = array();
|
||||
|
||||
// Tokenize the current and previous gateway names.
|
||||
$curr_tokens = preg_split( '/[ :,\-_]+/', $key );
|
||||
$prev_tokens = preg_split( '/[ :,\-_]+/', $prev );
|
||||
|
||||
$len_curr = count( $curr_tokens );
|
||||
$len_prev = count( $prev_tokens );
|
||||
|
||||
$index_unique = -1;
|
||||
// Gather the common tokens.
|
||||
// Let us allow for the unique reference id to be anywhere in the name.
|
||||
for ( $i = 0; $i < $len_curr && $i < $len_prev; $i++ ) {
|
||||
if ( $curr_tokens[ $i ] === $prev_tokens[ $i ] ) {
|
||||
$comm_tokens[] = $curr_tokens[ $i ];
|
||||
} elseif ( preg_match( '/\d/', $curr_tokens[ $i ] ) && preg_match( '/\d/', $prev_tokens[ $i ] ) ) {
|
||||
$index_unique = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// If only one token is different, and those tokens contain digits, then that could be the unique id.
|
||||
if ( count( $curr_tokens ) - count( $comm_tokens ) <= 1 && count( $comm_tokens ) > 0 && $index_unique > -1 ) {
|
||||
$objects[ $key ]->group_key = implode( ' ', $comm_tokens );
|
||||
$objects[ $prev ]->group_key = implode( ' ', $comm_tokens );
|
||||
} else {
|
||||
$objects[ $key ]->group_key = $objects[ $key ]->$default_key;
|
||||
}
|
||||
} else {
|
||||
$objects[ $key ]->group_key = $objects[ $key ]->$default_key;
|
||||
}
|
||||
$prev = $key;
|
||||
}
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order details by gateway.
|
||||
*
|
||||
|
@ -506,7 +569,7 @@ class WC_Tracker {
|
|||
private static function get_orders_by_gateway() {
|
||||
global $wpdb;
|
||||
|
||||
$orders_by_gateway = $wpdb->get_results(
|
||||
$orders_and_gateway_details = $wpdb->get_results(
|
||||
"
|
||||
SELECT
|
||||
gateway, currency, SUM(total) AS totals, COUNT(order_id) AS counts
|
||||
|
@ -530,14 +593,56 @@ class WC_Tracker {
|
|||
);
|
||||
|
||||
$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;
|
||||
// The associative array that is created as the result of array_reduce is passed to extract_group_key()
|
||||
// This function has the logic that will remove specific transaction identifiers that may sometimes be part of a
|
||||
// payment method. For example, two payments methods like 'WooDataPay ** #123' and 'WooDataPay ** #78' would
|
||||
// both have the same group_key 'WooDataPay **'.
|
||||
$orders_by_gateway = self::extract_group_key(
|
||||
// Convert into an associative array with a combination of currency and gateway as key.
|
||||
array_reduce(
|
||||
$orders_and_gateway_details,
|
||||
function( $result, $item ) {
|
||||
$item->gateway = preg_replace( '/\s+/', ' ', $item->gateway );
|
||||
|
||||
// Introduce currency as a prefix for the key.
|
||||
$key = $item->currency . '==' . $item->gateway;
|
||||
|
||||
$result[ $key ] = $item;
|
||||
return $result;
|
||||
},
|
||||
array()
|
||||
),
|
||||
'gateway'
|
||||
);
|
||||
|
||||
// Aggregate using group_key.
|
||||
foreach ( $orders_by_gateway as $orders_details ) {
|
||||
$gkey = $orders_details->group_key;
|
||||
|
||||
// Remove currency as prefix of key for backward compatibility.
|
||||
if ( str_contains( $gkey, '==' ) ) {
|
||||
$tokens = preg_split( '/==/', $gkey );
|
||||
$key = $tokens[1];
|
||||
} else {
|
||||
$key = $gkey;
|
||||
}
|
||||
|
||||
$key = str_replace( array( 'payment method', 'payment gateway', 'gateway' ), '', strtolower( $key ) );
|
||||
$key = trim( preg_replace( '/[: ,#*\-_]+/', ' ', $key ) );
|
||||
|
||||
// Add currency as postfix of gateway for backward compatibility.
|
||||
$key = 'gateway_' . $key . '_' . $orders_details->currency;
|
||||
$count_key = $key . '_count';
|
||||
$total_key = $key . '_total';
|
||||
|
||||
if ( array_key_exists( $count_key, $orders_by_gateway_currency ) || array_key_exists( $total_key, $orders_by_gateway_currency ) ) {
|
||||
$orders_by_gateway_currency[ $count_key ] = $orders_by_gateway_currency[ $count_key ] + $orders_details->counts;
|
||||
$orders_by_gateway_currency[ $total_key ] = $orders_by_gateway_currency[ $total_key ] + $orders_details->totals;
|
||||
} else {
|
||||
$orders_by_gateway_currency[ $count_key ] = $orders_details->counts;
|
||||
$orders_by_gateway_currency[ $total_key ] = $orders_details->totals;
|
||||
}
|
||||
}
|
||||
|
||||
return $orders_by_gateway_currency;
|
||||
|
@ -566,9 +671,35 @@ class WC_Tracker {
|
|||
"
|
||||
);
|
||||
|
||||
// The associative array that is created as the result of array_reduce is passed to extract_group_key()
|
||||
// This function has the logic that will remove specific identifiers that may sometimes be part of an origin.
|
||||
// For example, two origins like 'Import #123' and 'Import ** #78' would both have a group_key 'Import **'.
|
||||
$orders_and_origins = self::extract_group_key(
|
||||
// Convert into an associative array with the origin as key.
|
||||
array_reduce(
|
||||
$orders_origin,
|
||||
function( $result, $item ) {
|
||||
$key = $item->origin;
|
||||
|
||||
$result[ $key ] = $item;
|
||||
return $result;
|
||||
},
|
||||
array()
|
||||
),
|
||||
'origin'
|
||||
);
|
||||
|
||||
$orders_by_origin = array();
|
||||
foreach ( $orders_origin as $origin ) {
|
||||
$orders_by_origin[ $origin->origin ] = (int) $origin->count;
|
||||
|
||||
// Aggregate using group_key.
|
||||
foreach ( $orders_and_origins as $origin ) {
|
||||
$key = strtolower( $origin->group_key );
|
||||
|
||||
if ( array_key_exists( $key, $orders_by_origin ) ) {
|
||||
$orders_by_origin[ $key ] = $orders_by_origin[ $key ] + (int) $origin->count;
|
||||
} else {
|
||||
$orders_by_origin[ $key ] = (int) $origin->count;
|
||||
}
|
||||
}
|
||||
|
||||
return array( 'created_via' => $orders_by_origin );
|
||||
|
|
Loading…
Reference in New Issue