<?php
namespace WCML\Multicurrency\Analytics;
use WCML\COT\Helper as COTHelper;
use WCML\Orders\Helper as OrdersHelper;
use WCML\Utilities\Resources;
use WCML\Rest\Functions;
use WCML\StandAlone\IStandAloneAction;
use WPML\FP\Obj;
use WPML\FP\Fns;
use WCML\Utilities\WpAdminPages;
class Hooks implements \IWPML_Action, IStandAloneAction {
/** @var \woocommerce_wpml $woocommerce_wpml */
private $woocommerce_wpml;
/** @var \wpdb $wpdb */
private $wpdb;
/** @var string $requestedCurrencyForReport */
private $requestedCurrencyForReport;
public function __construct( \woocommerce_wpml $woocommerce_wpml, \wpdb $wpdb ) {
$this->woocommerce_wpml = $woocommerce_wpml;
$this->wpdb = $wpdb;
}
public function add_hooks() {
if ( Functions::isAnalyticsPage() ) {
add_action( 'admin_enqueue_scripts', [ $this, 'enqueueAssets' ] );
}
wpml_collect(
[
'revenue',
'orders',
'orders_stats',
'products',
'products_stats',
'categories',
'coupons',
'coupons_stats',
'taxes',
'taxes_stats',
'variations',
'variations_stats',
]
)->each(
function( $item ) {
add_filter( "woocommerce_analytics_{$item}_query_args", [ $this, 'addCurrencyArg' ] );
}
);
wpml_collect(
[
'products',
'orders',
'variations',
'categories',
'coupons',
'taxes',
]
)->each(
function( $item ) {
add_filter( "woocommerce_analytics_clauses_where_{$item}_subquery", [ $this, 'addWhere' ] );
add_filter( "woocommerce_analytics_clauses_where_{$item}_stats_total", [ $this, 'addWhere' ] );
add_filter( "woocommerce_analytics_clauses_where_{$item}_stats_interval", [ $this, 'addWhere' ] );
}
);
add_action( 'woocommerce_admin_report_export', [ $this, 'saveRequestedCurrencyForReport' ], -PHP_INT_MAX, 4 );
}
public function enqueueAssets() {
$multiCurrency = $this->woocommerce_wpml->get_multi_currency();
$currencies = $multiCurrency->get_currency_codes();
$enqueue = Resources::enqueueApp( 'multicurrencyAnalytics' );
$enqueue(
[
'name' => 'wcmlAnalytics',
'data' => [
'strings' => [
'currencyLabel' => __( 'Currency', 'woocommerce-multilingual' ),
],
'filterItems' => $this->getCurrencyFilterItems( $currencies ),
'currencyConfigs' => $this->getCurrencyConfigs( $currencies, $multiCurrency ),
],
]
);
}
/**
* Labels for the currency dropdown (filter).
*
* @param array $currencies
*
* @return array
*/
private function getCurrencyFilterItems( $currencies ) {
$currencyLabels = get_woocommerce_currencies();
return wpml_collect( $currencies )
->map(
function( $currency ) use ( $currencyLabels ) {
return [
'value' => $currency,
'label' => $currencyLabels[ $currency ],
];
}
)->toArray();
}
/**
* Currency settings for displaying prices.
*
* @param array $currencies
* @param \WCML_Multi_Currency $multiCurrency
*
* @return array
*/
private function getCurrencyConfigs( $currencies, $multiCurrency ) {
return wpml_collect( $currencies )
->mapWithKeys(
function( $currency ) use ( $multiCurrency ) {
$get = Obj::prop( Fns::__, $multiCurrency->get_currency_details_by_code( $currency ) );
return [
$currency => [
'code' => $currency,
'symbol' => html_entity_decode( get_woocommerce_currency_symbol( $currency ) ),
'symbolPosition' => $get( 'position' ),
'thousandSeparator' => $get( 'thousand_sep' ),
'decimalSeparator' => $get( 'decimal_sep' ),
'precision' => $get( 'num_decimals' ),
],
];
}
)->toArray();
}
/**
* @param array $args
*
* @return array
*/
public function addCurrencyArg( $args ) {
return Obj::assoc( 'currency', $this->getCurrency(), $args );
}
/**
* @param array $clauses
*
* @return array
*/
public function addWhere( $clauses ) {
if ( COTHelper::isUsageEnabled() ) {
$orderTable = COTHelper::getTableName();
$clauses[] = $this->wpdb->prepare(
"AND EXISTS (
SELECT 1 FROM {$orderTable}
WHERE id = {$this->wpdb->prefix}wc_order_stats.order_id
AND currency = %s
)",
$this->getCurrency()
);
} else {
$clauses[] = $this->wpdb->prepare(
"AND EXISTS (
SELECT 1 FROM {$this->wpdb->postmeta}
WHERE post_id = {$this->wpdb->prefix}wc_order_stats.order_id
AND meta_key = '" . OrdersHelper::KEY_LEGACY_CURRENCY . "'
AND meta_value = %s
)",
$this->getCurrency()
);
}
return $clauses;
}
/**
* @param int $page
* @param string $id
* @param string $type
* @param array $args
*/
public function saveRequestedCurrencyForReport( $page, $id, $type, $args ) {
if ( 'orders' === $type && isset( $args['currency'] ) ) {
$this->requestedCurrencyForReport = $args['currency'];
}
}
private function getCurrency() {
if ( ! empty( $this->requestedCurrencyForReport ) ) {
return $this->requestedCurrencyForReport;
}
$rawCurrency = WpAdminPages::isDashboard()
? Obj::prop( '_wcml_dashboard_currency', $_COOKIE )
: Obj::prop( 'currency', $_GET );
return $rawCurrency
? sanitize_text_field( wp_unslash( $rawCurrency ) )
: wcml_get_woocommerce_currency_option();
}
}