rebase on oct-10-2023
This commit is contained in:
@@ -11,15 +11,20 @@
|
||||
*/
|
||||
|
||||
use Automattic\Jetpack\Constants;
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
||||
use Automattic\WooCommerce\Utilities\{ FeaturesUtil, OrderUtil, PluginUtil };
|
||||
use Automattic\WooCommerce\Internal\Utilities\BlocksUtil;
|
||||
use Automattic\WooCommerce\Proxies\LegacyProxy;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// phpcs:disable Squiz.Classes.ClassFileName.NoMatch, Squiz.Classes.ValidClassName.NotCamelCaps -- Backwards compatibility.
|
||||
/**
|
||||
* WooCommerce Tracker Class
|
||||
*/
|
||||
class WC_Tracker {
|
||||
|
||||
// phpcs:enable
|
||||
/**
|
||||
* URL to the WooThemes Tracker API endpoint.
|
||||
*
|
||||
@@ -30,7 +35,7 @@ class WC_Tracker {
|
||||
/**
|
||||
* Hook into cron event.
|
||||
*/
|
||||
public static function init() {
|
||||
public static function init() { // phpcs:ignore WooCommerce.Functions.InternalInjectionMethod.MissingFinal, WooCommerce.Functions.InternalInjectionMethod.MissingInternalTag -- Not an injection.
|
||||
add_action( 'woocommerce_tracker_send_event', array( __CLASS__, 'send_tracking_data' ) );
|
||||
}
|
||||
|
||||
@@ -45,10 +50,15 @@ class WC_Tracker {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter whether to send tracking data or not.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*/
|
||||
if ( ! apply_filters( 'woocommerce_tracker_send_override', $override ) ) {
|
||||
// Send a maximum of once per week by default.
|
||||
$last_send = self::get_last_send_time();
|
||||
if ( $last_send && $last_send > apply_filters( 'woocommerce_tracker_last_send_interval', strtotime( '-1 week' ) ) ) {
|
||||
if ( $last_send && $last_send > apply_filters( 'woocommerce_tracker_last_send_interval', strtotime( '-1 week' ) ) ) { // phpcs:ignore
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -84,6 +94,11 @@ class WC_Tracker {
|
||||
* @return int|bool
|
||||
*/
|
||||
private static function get_last_send_time() {
|
||||
/**
|
||||
* Filter the last time tracking data was sent.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*/
|
||||
return apply_filters( 'woocommerce_tracker_last_send_time', get_option( 'woocommerce_tracker_last_send', false ) );
|
||||
}
|
||||
|
||||
@@ -118,7 +133,12 @@ class WC_Tracker {
|
||||
$data = array();
|
||||
|
||||
// General site info.
|
||||
$data['url'] = home_url();
|
||||
$data['url'] = home_url();
|
||||
/**
|
||||
* Filter the admin email that's sent with data.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*/
|
||||
$data['email'] = apply_filters( 'woocommerce_tracker_admin_email', get_option( 'admin_email' ) );
|
||||
$data['theme'] = self::get_theme_info();
|
||||
|
||||
@@ -134,7 +154,6 @@ class WC_Tracker {
|
||||
$data['inactive_plugins'] = $all_plugins['inactive_plugins'];
|
||||
|
||||
// Jetpack & WooCommerce Connect.
|
||||
|
||||
$data['jetpack_version'] = Constants::is_defined( 'JETPACK__VERSION' ) ? Constants::get_constant( 'JETPACK__VERSION' ) : 'none';
|
||||
$data['jetpack_connected'] = ( class_exists( 'Jetpack' ) && is_callable( 'Jetpack::is_active' ) && Jetpack::is_active() ) ? 'yes' : 'no';
|
||||
$data['jetpack_is_staging'] = self::is_jetpack_staging_site() ? 'yes' : 'no';
|
||||
@@ -158,6 +177,9 @@ class WC_Tracker {
|
||||
// Shipping method info.
|
||||
$data['shipping_methods'] = self::get_active_shipping_methods();
|
||||
|
||||
// Features.
|
||||
$data['enabled_features'] = self::get_enabled_features();
|
||||
|
||||
// Get all WooCommerce options info.
|
||||
$data['settings'] = self::get_all_woocommerce_options_values();
|
||||
|
||||
@@ -172,12 +194,21 @@ class WC_Tracker {
|
||||
$data['mini_cart_block'] = self::get_mini_cart_info();
|
||||
}
|
||||
|
||||
// WooCommerce Admin info.
|
||||
/**
|
||||
* Filter whether to disable admin tracking.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
$data['wc_admin_disabled'] = apply_filters( 'woocommerce_admin_disabled', false ) ? 'yes' : 'no';
|
||||
|
||||
// Mobile info.
|
||||
$data['wc_mobile_usage'] = self::get_woocommerce_mobile_usage();
|
||||
|
||||
/**
|
||||
* Filter the data that's sent with the tracker.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*/
|
||||
return apply_filters( 'woocommerce_tracker_data', $data );
|
||||
}
|
||||
|
||||
@@ -212,6 +243,7 @@ class WC_Tracker {
|
||||
$memory = wc_let_to_num( WP_MEMORY_LIMIT );
|
||||
|
||||
if ( function_exists( 'memory_get_usage' ) ) {
|
||||
// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- False positive.
|
||||
$system_memory = wc_let_to_num( @ini_get( 'memory_limit' ) );
|
||||
$memory = max( $memory, $system_memory );
|
||||
}
|
||||
@@ -280,27 +312,31 @@ class WC_Tracker {
|
||||
include ABSPATH . '/wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
$plugins = get_plugins();
|
||||
$plugins = wc_get_container()->get( LegacyProxy::class )->call_function( 'get_plugins' );
|
||||
$active_plugins_keys = get_option( 'active_plugins', array() );
|
||||
$active_plugins = array();
|
||||
|
||||
foreach ( $plugins as $k => $v ) {
|
||||
// Take care of formatting the data how we want it.
|
||||
$formatted = array();
|
||||
$formatted['name'] = strip_tags( $v['Name'] );
|
||||
$formatted['name'] = wp_strip_all_tags( $v['Name'] );
|
||||
if ( isset( $v['Version'] ) ) {
|
||||
$formatted['version'] = strip_tags( $v['Version'] );
|
||||
$formatted['version'] = wp_strip_all_tags( $v['Version'] );
|
||||
}
|
||||
if ( isset( $v['Author'] ) ) {
|
||||
$formatted['author'] = strip_tags( $v['Author'] );
|
||||
$formatted['author'] = wp_strip_all_tags( $v['Author'] );
|
||||
}
|
||||
if ( isset( $v['Network'] ) ) {
|
||||
$formatted['network'] = strip_tags( $v['Network'] );
|
||||
$formatted['network'] = wp_strip_all_tags( $v['Network'] );
|
||||
}
|
||||
if ( isset( $v['PluginURI'] ) ) {
|
||||
$formatted['plugin_uri'] = strip_tags( $v['PluginURI'] );
|
||||
$formatted['plugin_uri'] = wp_strip_all_tags( $v['PluginURI'] );
|
||||
}
|
||||
if ( in_array( $k, $active_plugins_keys ) ) {
|
||||
$formatted['feature_compatibility'] = array();
|
||||
if ( wc_get_container()->get( PluginUtil::class )->is_woocommerce_aware_plugin( $k ) ) {
|
||||
$formatted['feature_compatibility'] = array_filter( FeaturesUtil::get_compatible_features_for_plugin( $k ) );
|
||||
}
|
||||
if ( in_array( $k, $active_plugins_keys, true ) ) {
|
||||
// Remove active plugins from list so we can show active and inactive separately.
|
||||
unset( $plugins[ $k ] );
|
||||
$active_plugins[ $k ] = $formatted;
|
||||
@@ -381,10 +417,9 @@ class WC_Tracker {
|
||||
* @return array
|
||||
*/
|
||||
private static function get_order_counts() {
|
||||
$order_count = array();
|
||||
$order_count_data = wp_count_posts( 'shop_order' );
|
||||
$order_count = array();
|
||||
foreach ( wc_get_order_statuses() as $status_slug => $status_name ) {
|
||||
$order_count[ $status_slug ] = $order_count_data->{ $status_slug };
|
||||
$order_count[ $status_slug ] = wc_orders_count( $status_slug );
|
||||
}
|
||||
return $order_count;
|
||||
}
|
||||
@@ -413,33 +448,59 @@ class WC_Tracker {
|
||||
private static function get_order_totals() {
|
||||
global $wpdb;
|
||||
|
||||
$gross_total = $wpdb->get_var(
|
||||
$orders_table = OrdersTableDataStore::get_orders_table_name();
|
||||
|
||||
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$gross_total = $wpdb->get_var(
|
||||
"
|
||||
SELECT SUM(total_amount) AS 'gross_total'
|
||||
FROM $orders_table
|
||||
WHERE status in ('wc-completed', 'wc-refunded');
|
||||
"
|
||||
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
|
||||
"
|
||||
);
|
||||
);
|
||||
// phpcs:enable
|
||||
} else {
|
||||
$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
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
if ( is_null( $gross_total ) ) {
|
||||
$gross_total = 0;
|
||||
}
|
||||
|
||||
$processing_gross_total = $wpdb->get_var(
|
||||
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$processing_gross_total = $wpdb->get_var(
|
||||
"
|
||||
SELECT SUM(total_amount) AS 'gross_total'
|
||||
FROM $orders_table
|
||||
WHERE status = 'wc-processing';
|
||||
"
|
||||
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
|
||||
"
|
||||
);
|
||||
);
|
||||
// phpcs:enable
|
||||
} else {
|
||||
$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;
|
||||
@@ -459,16 +520,31 @@ class WC_Tracker {
|
||||
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
|
||||
);
|
||||
$orders_table = OrdersTableDataStore::get_orders_table_name();
|
||||
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$min_max = $wpdb->get_row(
|
||||
"
|
||||
SELECT
|
||||
MIN( date_created_gmt ) as 'first', MAX( date_created_gmt ) as 'last'
|
||||
FROM $orders_table
|
||||
WHERE status = 'wc-completed';
|
||||
",
|
||||
ARRAY_A
|
||||
);
|
||||
// phpcs:enable
|
||||
} else {
|
||||
$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(
|
||||
@@ -477,16 +553,30 @@ class WC_Tracker {
|
||||
);
|
||||
}
|
||||
|
||||
$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 ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$processing_min_max = $wpdb->get_row(
|
||||
"
|
||||
SELECT
|
||||
MIN( date_created_gmt ) as 'processing_first', MAX( date_created_gmt ) as 'processing_last'
|
||||
FROM $orders_table
|
||||
WHERE status = 'wc-processing';
|
||||
",
|
||||
ARRAY_A
|
||||
);
|
||||
// phpcs:enable
|
||||
} else {
|
||||
$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(
|
||||
@@ -498,6 +588,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,38 +659,94 @@ class WC_Tracker {
|
||||
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 (
|
||||
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||
$orders_table = OrdersTableDataStore::get_orders_table_name();
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$orders_and_gateway_details = $wpdb->get_results(
|
||||
"
|
||||
SELECT payment_method AS gateway, currency AS currency, SUM( total_amount ) AS totals, count( id ) AS counts
|
||||
FROM $orders_table
|
||||
WHERE status IN ( 'wc-completed', 'wc-processing', 'wc-refunded' )
|
||||
GROUP BY gateway, currency;
|
||||
"
|
||||
);
|
||||
// phpcs:enable
|
||||
} else {
|
||||
$orders_and_gateway_details = $wpdb->get_results(
|
||||
"
|
||||
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
|
||||
"
|
||||
);
|
||||
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;
|
||||
// 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;
|
||||
@@ -551,24 +760,63 @@ class WC_Tracker {
|
||||
private static function get_orders_origins() {
|
||||
global $wpdb;
|
||||
|
||||
$orders_origin = $wpdb->get_results(
|
||||
"
|
||||
SELECT
|
||||
meta_value as origin, COUNT( DISTINCT ( orders.id ) ) as count
|
||||
FROM
|
||||
$wpdb->posts orders
|
||||
LEFT JOIN
|
||||
$wpdb->postmeta order_meta ON order_meta.post_id = orders.id
|
||||
WHERE
|
||||
meta_key = '_created_via'
|
||||
GROUP BY
|
||||
meta_value;
|
||||
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||
$op_table_name = OrdersTableDataStore::get_operational_data_table_name();
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$orders_origin = $wpdb->get_results(
|
||||
"
|
||||
SELECT created_via as origin, COUNT( order_id ) as count
|
||||
FROM $op_table_name
|
||||
GROUP BY created_via;
|
||||
"
|
||||
);
|
||||
// phpcs:enable
|
||||
} else {
|
||||
$orders_origin = $wpdb->get_results(
|
||||
"
|
||||
SELECT
|
||||
meta_value as origin, COUNT( DISTINCT ( orders.id ) ) as count
|
||||
FROM
|
||||
$wpdb->posts orders
|
||||
LEFT JOIN
|
||||
$wpdb->postmeta order_meta ON order_meta.post_id = orders.id
|
||||
WHERE
|
||||
meta_key = '_created_via'
|
||||
GROUP BY
|
||||
meta_value;
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
// 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 );
|
||||
@@ -663,6 +911,23 @@ class WC_Tracker {
|
||||
return $active_methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of slugs for WC features that are enabled on the site.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private static function get_enabled_features() {
|
||||
$all_features = FeaturesUtil::get_features( true, true );
|
||||
$enabled_features = array_filter(
|
||||
$all_features,
|
||||
function( $feature ) {
|
||||
return $feature['is_enabled'];
|
||||
}
|
||||
);
|
||||
|
||||
return array_keys( $enabled_features );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all options starting with woocommerce_ prefix.
|
||||
*
|
||||
@@ -705,7 +970,12 @@ class WC_Tracker {
|
||||
* @return array
|
||||
*/
|
||||
private static function get_all_template_overrides() {
|
||||
$override_data = array();
|
||||
$override_data = array();
|
||||
/**
|
||||
* Filter the paths to scan for template overrides.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*/
|
||||
$template_paths = apply_filters( 'woocommerce_template_overrides_scan_paths', array( 'WooCommerce' => WC()->plugin_path() . '/templates/' ) );
|
||||
$scanned_files = array();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user