laoyang
4beb09307c
3.2.17: 修复「保存设置时静默清空未提交的字段」
现象
在主题设置里填了「附加日期」(例如 10-23),过一阵发现它变回空了,
于是当天的哀悼效果不再出现,而其他设置都好好的,看不出哪里坏了。
根因
inc/options-framework/includes/class-options-framework-admin.php 的
validate_options() 里,对每个选项无条件取 $input[$id] 去 sanitize:
$clean[$id] = apply_filters('of_sanitize_'.$type, $input[$id], $option);
一旦某次提交里没有这个键(分组没渲染、字段被条件隐藏、表单中途出错只
提交了一半……),$input[$id] 是未定义索引 ⇒ null ⇒ sanitize_text_field()
返回空串 ⇒ 把用户存了很久的配置写成空。而且"清成空串"和"用户主动清空"
在库里完全一样,事后无法区分,只表现为"我明明填过,怎么没了"。
实测证据(线上 PHP 8.5.12,同一套用例)
修复前:3 通过 / 2 失败,失败项同时伴随
PHP Warning: Undefined array key "g_rip_extra" ... line 252
修复后:5 通过 / 0 失败
改法
- 循环外先取一次 get_option('kratos') 作 $saved_options(不在循环里查库)
- 提交了(array_key_exists($id,$input))才 sanitize
- 没提交则沿用 $saved_options 里的旧值;旧值也没有就不写这个键,
让运行时的默认值继续生效
- checkbox / multicheck 保持原语义:这两类"没提交"确实等于"没勾",
沿用旧值会导致开关关不掉。用 $is_toggle 单独判定,与"沿用旧值"互斥
为什么这个改动值得单独发一版
它不是界面问题,是**数据被静默改写**。凡是这种"用户没动、值却变了"的
缺陷,都会让人怀疑数据不可靠;而且每次后台保存都可能再触发一次。
验证
- 线上 _test_keep_old_value.php:5/5(修复前 3/5,用例 2 精确复现空串)
- 本地 _static_317.php:8/8,第 4 组自带注入(改成老写法必须变红)
- 全量流水线 verify_all.sh:rc=0
- 线上浏览器 _live315.py:纪念日分支 33/33、非纪念日分支 27/27
(判据改为「由配置侧独立算 expect_show,再与页面渲染对比」,
不再无条件断言"必须有灰度",也不再拿页面自身当预期值)
2026-10-23 23:18:51 +08:00
..
2026-10-23 23:18:51 +08:00
2022-01-07 11:15:42 +08:00
2026-10-23 13:55:23 +08:00
2022-01-07 11:15:42 +08:00
2026-10-23 13:55:23 +08:00