-
Notifications
You must be signed in to change notification settings - Fork 69
/
class-wc-payments-localization-service.php
146 lines (126 loc) · 4.12 KB
/
class-wc-payments-localization-service.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
/**
* WooCommerce Payments WC_Payments_Localization_Service Class
*
* @package WooCommerce\Payments
*/
defined( 'ABSPATH' ) || exit;
/**
* WC_Payments_Localization_Service.
*/
class WC_Payments_Localization_Service {
const WCPAY_CURRENCY_FORMAT_TRANSIENT = 'wcpay_currency_format';
const WCPAY_LOCALE_INFO_TRANSIENT = 'wcpay_locale_info';
/**
* Currency formatting map.
*
* @var array
*/
protected $currency_format = [];
/**
* Currency locale info.
*
* @var array
*/
protected $locale_info = [];
/**
* Constructor.
*/
public function __construct() {
$this->load_locale_data();
}
/**
* Retrieves the currency's format from mapped data.
*
* @param string $currency_code The currency code.
*
* @return array The currency's format.
*/
public function get_currency_format( $currency_code ): array {
// Default to USD settings if mapping not found.
$currency_format = [
'currency_pos' => 'left',
'thousand_sep' => ',',
'decimal_sep' => '.',
'num_decimals' => 2,
];
$locale = $this->get_user_locale();
$currency_options = $this->currency_format[ $currency_code ] ?? null;
if ( $currency_options ) {
// If there's no locale-specific formatting, default to the 'default' entry in the array.
$currency_format = $currency_options[ $locale ] ?? $currency_options['default'] ?? $currency_format;
}
/**
* Filter to edit formatting for a specific currency (wcpay_{currency_code}_format).
*
* This filter can be used to override the currency format for a specific currency.
* The currency code in the filter name should be used in lowercase.
*
* @since 2.8.0
*
* @param array $currency_format The currency format settings.
* @param string $locale The user's locale.
*/
return apply_filters( 'wcpay_' . strtolower( $currency_code ) . '_format', $currency_format, $locale );
}
/**
* Returns the user locale.
*
* @return string The locale.
*/
public function get_user_locale(): string {
return get_user_locale();
}
// TODO: Add tests.
/**
* Returns the locale data for a country.
*
* @param string $country Country code.
*
* @return array Array with the country's locale data. Empty array if country not found.
*/
public function get_country_locale_data( $country ): array {
return $this->locale_info[ $country ] ?? [];
}
/**
* Loads locale data from WooCommerce core (/i18n/locale-info.php) and maps it
* to be used by currency.
*
* @return void
*/
private function load_locale_data() {
$transient_currency_format_data = get_transient( self::WCPAY_CURRENCY_FORMAT_TRANSIENT );
$transient_locale_info_data = get_transient( self::WCPAY_LOCALE_INFO_TRANSIENT );
if ( $transient_currency_format_data && $transient_locale_info_data ) {
$this->currency_format = $transient_currency_format_data;
$this->locale_info = $transient_locale_info_data;
return;
}
$locale_info_path = WC()->plugin_path() . '/i18n/locale-info.php';
// The full locale data was introduced in the currency-info.php file.
// If it doesn't exist we have to use the fallback.
if ( ! file_exists( WC()->plugin_path() . '/i18n/currency-info.php' ) ) {
$locale_info_path = WCPAY_ABSPATH . 'i18n/locale-info.php';
}
$this->locale_info = include $locale_info_path;
if ( is_array( $this->locale_info ) && 0 < count( $this->locale_info ) ) {
// Extract the currency formatting options from the locale info.
foreach ( $this->locale_info as $country_data ) {
$currency_code = $country_data['currency_code'];
foreach ( $country_data['locales'] as $locale => $locale_data ) {
if ( empty( $locale_data ) ) {
continue;
}
$this->currency_format[ $currency_code ][ $locale ] = [
'currency_pos' => $locale_data['currency_pos'],
'thousand_sep' => $locale_data['thousand_sep'],
'decimal_sep' => $locale_data['decimal_sep'],
'num_decimals' => $country_data['num_decimals'],
];
}
}
set_transient( self::WCPAY_CURRENCY_FORMAT_TRANSIENT, $this->currency_format, DAY_IN_SECONDS );
set_transient( self::WCPAY_LOCALE_INFO_TRANSIENT, $this->locale_info, DAY_IN_SECONDS );
}
}
}