Files
WooNooW/includes/Compat/StoreSettingsProvider.php
dwindown 42eb8eb441 fix: Critical payment toggle sync and 3rd party gateway settings
 Issue 1: Toggle Not Saving (CRITICAL FIX)
Problem: Toggle appeared to work but didn't persist
Root Cause: Missing query invalidation after toggle
Solution:
- Added queryClient.invalidateQueries after successful toggle
- Now fetches real server state after optimistic update
- Ensures SPA and WooCommerce stay in sync

 Issue 2: SearchableSelect Default Value
Problem: Showing 'Select country...' when Indonesia selected
Root Cause: WooCommerce stores country as 'ID:DKI_JAKARTA'
Solution:
- Split country:state format in backend
- Extract country code only for select
- Added timezone fallback to 'UTC' if empty

 Issue 3: 3rd Party Gateway Settings
Problem: TriPay showing 'Configure in WooCommerce' link
Solution:
- Replaced external link with Settings button
- Now opens GenericGatewayForm modal
- All WC form_fields render automatically
- TriPay fields (enable_icon, expired, checkout_method) work!

📋 Files Modified:
- Payments.tsx: Added invalidation + settings button
- StoreSettingsProvider.php: Split country format
- All 3rd party gateways now configurable in SPA

🎯 Result:
 Toggle saves correctly to WooCommerce
 Country/timezone show selected values
 All gateways with form_fields are editable
 No more 'Configure in WooCommerce' for compliant gateways
2025-11-05 22:41:02 +07:00

175 lines
5.8 KiB
PHP

<?php
/**
* Store Settings Provider
*
* Provides store settings data including countries, timezones, currencies, etc.
*
* @package WooNooW
*/
namespace WooNooW\Compat;
class StoreSettingsProvider {
/**
* Get all countries from WooCommerce
*
* @return array List of countries
*/
public static function get_countries(): array {
if (!class_exists('WC_Countries')) {
return [];
}
$wc_countries = new \WC_Countries();
$countries = $wc_countries->get_countries();
$formatted = [];
foreach ($countries as $code => $name) {
$formatted[] = [
'code' => $code,
'name' => $name,
];
}
return $formatted;
}
/**
* Get all timezones
*
* @return array List of timezones
*/
public static function get_timezones(): array {
$timezones = timezone_identifiers_list();
$formatted = [];
foreach ($timezones as $timezone) {
// Group by continent
$parts = explode('/', $timezone);
$continent = $parts[0] ?? 'Other';
if (!isset($formatted[$continent])) {
$formatted[$continent] = [];
}
// Format display name
$display = str_replace('_', ' ', $timezone);
// Get UTC offset
try {
$tz = new \DateTimeZone($timezone);
$now = new \DateTime('now', $tz);
$offset = $tz->getOffset($now);
$hours = floor($offset / 3600);
$minutes = abs(floor(($offset % 3600) / 60));
$offset_string = sprintf('UTC%+d:%02d', $hours, $minutes);
} catch (\Exception $e) {
$offset_string = 'UTC';
}
$formatted[$continent][] = [
'value' => $timezone,
'label' => $display,
'offset' => $offset_string,
];
}
return $formatted;
}
/**
* Get all currencies from WooCommerce
*
* @return array List of currencies
*/
public static function get_currencies(): array {
if (!function_exists('get_woocommerce_currencies')) {
return [];
}
$currencies = get_woocommerce_currencies();
$formatted = [];
foreach ($currencies as $code => $name) {
$symbol = get_woocommerce_currency_symbol($code);
$formatted[] = [
'code' => $code,
'name' => $name,
'symbol' => $symbol,
];
}
return $formatted;
}
/**
* Get store settings
*
* @return array Store settings
*/
public static function get_settings(): array {
// WooCommerce stores country as "COUNTRY:STATE" format
$default_country = get_option('woocommerce_default_country', '');
$country_parts = explode(':', $default_country);
$country_code = $country_parts[0] ?? '';
return [
'store_name' => get_option('blogname', ''),
'contact_email' => get_option('admin_email', ''),
'support_email' => get_option('woocommerce_email_from_address', ''),
'phone' => get_option('woocommerce_store_phone', ''),
'country' => $country_code,
'address' => get_option('woocommerce_store_address', ''),
'address_2' => get_option('woocommerce_store_address_2', ''),
'city' => get_option('woocommerce_store_city', ''),
'postcode' => get_option('woocommerce_store_postcode', ''),
'currency' => get_option('woocommerce_currency', 'USD'),
'currency_position' => get_option('woocommerce_currency_pos', 'left'),
'thousand_separator' => get_option('woocommerce_price_thousand_sep', ','),
'decimal_separator' => get_option('woocommerce_price_decimal_sep', '.'),
'number_of_decimals' => (int) get_option('woocommerce_price_num_decimals', 2),
'timezone' => get_option('timezone_string', 'UTC') ?: 'UTC',
'weight_unit' => get_option('woocommerce_weight_unit', 'kg'),
'dimension_unit' => get_option('woocommerce_dimension_unit', 'cm'),
];
}
/**
* Save store settings
*
* @param array $settings Settings to save
* @return bool True on success
*/
public static function save_settings(array $settings): bool {
$mapping = [
'store_name' => 'blogname',
'contact_email' => 'admin_email',
'support_email' => 'woocommerce_email_from_address',
'phone' => 'woocommerce_store_phone',
'country' => 'woocommerce_default_country',
'address' => 'woocommerce_store_address',
'address_2' => 'woocommerce_store_address_2',
'city' => 'woocommerce_store_city',
'postcode' => 'woocommerce_store_postcode',
'currency' => 'woocommerce_currency',
'currency_position' => 'woocommerce_currency_pos',
'thousand_separator' => 'woocommerce_price_thousand_sep',
'decimal_separator' => 'woocommerce_price_decimal_sep',
'number_of_decimals' => 'woocommerce_price_num_decimals',
'timezone' => 'timezone_string',
'weight_unit' => 'woocommerce_weight_unit',
'dimension_unit' => 'woocommerce_dimension_unit',
];
foreach ($settings as $key => $value) {
if (isset($mapping[$key])) {
update_option($mapping[$key], $value);
}
}
return true;
}
}