fix(payment): 结算货币旧小写值导致枚举校验失败无法保存
paypal_currency/stripe_currency 由自由文本改为 select 后,旧存储值(如 stripe_currency=usd 小写)不通过枚举校验,收款接口页保存被 422 拦截。 为两个货币字段增加 case_insensitive 归一化:读取时归一为选项规范写法、 写入时归一化、校验时大小写不敏感放行,匹配不到回退默认 USD。
This commit is contained in:
@@ -237,12 +237,14 @@ class SchemaProvider {
|
||||
// (legacy / SPA may still use type=select multiple).
|
||||
if (!empty($field['multiple']) && is_array($value)) {
|
||||
foreach ($value as $item) {
|
||||
if (!in_array($item, $valid_values, true)) {
|
||||
if (!in_array($item, $valid_values, true)
|
||||
&& (empty($field['case_insensitive']) || $this->normalize_case_insensitive_option($item, (array) $field['options']) === null)) {
|
||||
$errors[] = sprintf('%s has an invalid value', $field['label'] ?? $key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} elseif (!in_array($value, $valid_values, true)) {
|
||||
} elseif (!in_array($value, $valid_values, true)
|
||||
&& (empty($field['case_insensitive']) || $this->normalize_case_insensitive_option($value, (array) $field['options']) === null)) {
|
||||
$errors[] = sprintf('%s has an invalid value', $field['label'] ?? $key);
|
||||
}
|
||||
}
|
||||
@@ -545,6 +547,12 @@ class SchemaProvider {
|
||||
if ($has_stored) {
|
||||
$data[$field['key']] = $stored[$field['key']];
|
||||
}
|
||||
// 大小写不敏感字段:存储值归一化为选项规范写法;匹配不到回退默认,
|
||||
// 避免旧自由文本值(如小写货币代码)导致枚举校验失败。
|
||||
if (!empty($field['case_insensitive']) && in_array($field_type, ['select', 'radio'], true) && !empty($field['options'])) {
|
||||
$normalized = $this->normalize_case_insensitive_option($data[$field['key']] ?? '', (array) $field['options']);
|
||||
$data[$field['key']] = $normalized !== null ? $normalized : ($field['default'] ?? ($data[$field['key']] ?? ''));
|
||||
}
|
||||
if (($field['sanitize_type'] ?? '') === 'money_decimal' && array_key_exists($field['key'], $data)) {
|
||||
$normalized = $this->normalize_money_decimal($data[$field['key']]);
|
||||
if ($normalized !== '') {
|
||||
@@ -855,6 +863,27 @@ class SchemaProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对大小写不敏感字段(case_insensitive),把值归一化为选项中的规范写法;
|
||||
* 匹配不到返回 null。
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param array<int,mixed> $options
|
||||
*/
|
||||
private function normalize_case_insensitive_option($value, array $options): ?string {
|
||||
if (!is_string($value) || $value === '') {
|
||||
return null;
|
||||
}
|
||||
$lower = strtolower(trim($value));
|
||||
foreach ($options as $opt) {
|
||||
$opt_value = is_array($opt) ? ($opt['value'] ?? null) : $opt;
|
||||
if (is_string($opt_value) && strtolower($opt_value) === $lower) {
|
||||
return $opt_value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function sanitize_field_value($value, array $field) {
|
||||
if (!empty($field['captcha_provider'])) {
|
||||
return function_exists('aksrt_captcha_sanitize_provider_config')
|
||||
@@ -874,6 +903,12 @@ class SchemaProvider {
|
||||
return $this->sanitize_value($value, 'attachment_ids');
|
||||
}
|
||||
|
||||
if (in_array($type, ['select', 'radio'], true) && !empty($field['case_insensitive']) && !empty($field['options'])) {
|
||||
// 旧自由文本值(如小写货币代码)归一化为选项规范写法。
|
||||
$normalized = $this->normalize_case_insensitive_option($value, (array) $field['options']);
|
||||
return $normalized !== null ? $normalized : (string) ($field['default'] ?? '');
|
||||
}
|
||||
|
||||
if (in_array($type, ['fieldset', 'accordion'], true)) {
|
||||
return $this->sanitize_object_fields($value, (array) ($field['fields'] ?? []));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user