fix(badges): keep the medal catalog from being cast to a string on save
user_medal_args was declared as type=json without sanitize_type, so sanitize_field_value() fell through to sanitize_text_field((string) $value) and stored the literal string "Array". validate() has no json shape check, so the save reported success. Consequence: parse_medal_catalog() json_decoded "Array" into an empty catalog, the dictionary came back empty, and user_context() dropped every owned badge — the front end showed "获取徽章" and the grant modal listed nothing, hiding both the newly added and the pre-existing badges. Add the missing sanitize_type to match its sibling level/integral fields, and guard sanitize_field_value() so structured container types can never reach the scalar fallback again. Mirrors the declaration in the Vue schema. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
5c6b422866
commit
4e62b325d2
3 files changed
+12
No files matched your search
@@ -134,6 +134,7 @@ export const badgeSchema = {
|
||||
key: 'user_medal_args',
|
||||
label: '分类与条目',
|
||||
type: 'json',
|
||||
sanitizeType: 'array',
|
||||
default: defaultMedalArgs(),
|
||||
help: '由自定义页编辑:分类 → 条目(slug/名称/描述/图标/get_type/get_val)。仅手动授予用 manually_add。',
|
||||
dependsOn: { key: 'user_medal_s', value: true },
|
||||
|
||||
@@ -557,6 +557,10 @@ class SchemaUsers {
|
||||
'key' => 'user_medal_args',
|
||||
'label' => '分类与条目',
|
||||
'type' => 'json',
|
||||
// Must be explicit: sanitize_field_value() only honours sanitize_type
|
||||
// on the write path. Without it the nested catalog is cast to the
|
||||
// literal string "Array", wiping every badge from the dictionary.
|
||||
'sanitize_type' => 'array',
|
||||
'default' => self::default_medal_args(),
|
||||
'help' => '结构化目录:分类 → 条目(slug/name/desc/icon/get_type/get_val)。由 SPA UsersBadge 编辑。',
|
||||
],
|
||||
|
||||
@@ -857,6 +857,13 @@ class SchemaProvider {
|
||||
return esc_url_raw((string) $value);
|
||||
}
|
||||
|
||||
// Structured container types must never reach the scalar fallback below:
|
||||
// casting a nested payload to string silently destroys it ("Array") and
|
||||
// validate() has no json/array shape check to catch the loss.
|
||||
if (in_array($type, ['json', 'repeater', 'sortable', 'group', 'fieldset', 'accordion'], true)) {
|
||||
return is_array($value) ? $value : [];
|
||||
}
|
||||
|
||||
return sanitize_text_field((string) $value);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user