3.2.35 CDN 加速加启用开关 + 预制白/黑名单,勾了不填地址拒绝保存 #4
「启用 CDN 加速」复选框放在 CDN 段最前。不勾时下面填什么都不产生作用, 前台与没装该功能完全一致(三个入口 should_rewrite / rewrite_html / buffer_start 都过 yang_cdn_active())。 预制名单写进输入框的 std,用户可直接增删改,保存后以用户内容为准: 白名单 13 项(.avif .css .gif .jpeg .jpg .js .json .mp3 .mp4 .pdf .png .svg .webp);黑名单 13 项安全后缀(.php* .phtml .phar .env .sql .bak .log .ini .sh .htaccess)。同时 yang_cdn_defaults() 给同一份 —— std 在运行时完全不生效,两处不同源就会出现「后台 13 项、前端 0 项」。 勾了开关但地址留空:保存被整单拒绝(validate_options 返回旧值),并 add_settings_error 提示。回调里绝不 update_option(会递归触发 sanitize_option_kratos,3.2.11 吃爆内存的路径)。另加 admin_init 进页面 提示,救「勾着但地址空」的老站点。 开关默认值按「地址是否非空」推算,老站点升级不丢加速;没填过地址的站点 默认不勾,避免第一次点保存就被「必须填地址」拦住。 顺带修掉 parse_url 对主机过于宽容导致的畸形地址(https://not a url at all 曾被当合法,会把全站静态资源拼成畸形地址)。 验证:_cdn335_logic.php 116/0 · _cdn335_falsify.php 22/0 · _admin335_cdn_check.py 74/0 · _admin335_falsify.py 23/0 · _pkgcheck335.py 117/0 · _pkgcheck335_falsify.py 27/0 · _cdn334_logic.php 92/0(向后兼容)· _cdn334_falsify.php 21/0
This commit is contained in:
@@ -63,6 +63,17 @@ class Options_Framework_Admin {
|
||||
add_action( 'optionsframework_after_validate', array( $this, 'save_options_notice' ) );
|
||||
|
||||
add_action( 'optionsframework_after_sendmail', array( $this, 'send_mail_notice' ) );
|
||||
|
||||
/*
|
||||
* 进设置页就检查 CDN 配置是否"勾了但没填地址"。
|
||||
*
|
||||
* 挂在 admin_init 上、在 options_page() 渲染之前跑,
|
||||
* 这样 add_settings_error 的结果会被页面里的 settings_errors() 显示。
|
||||
* 用 current_user_can 兜一层:虽然本类整体已经在
|
||||
* optionsframework_init 里判过权限,但这个钩子单独挂,
|
||||
* 以后若有人把它挪出去也不会漏权限判断。
|
||||
*/
|
||||
add_action( 'admin_init', array( $this, 'yang_cdn_config_notice' ), 21 );
|
||||
}
|
||||
|
||||
public function add_top_options_page()
|
||||
@@ -284,6 +295,65 @@ class Options_Framework_Admin {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ★ CDN 配置校验(3.2.35)
|
||||
*
|
||||
* 「勾了启用但地址为空」是**非法配置**,不是"关闭"。用户原话:
|
||||
* 「如果点了这个复选框,但是 CDN 地址不填,那就不行,得提示他
|
||||
* 说这个东西必须填。」所以这里拦住整个保存。
|
||||
*
|
||||
* ── 怎么做到"拒绝保存" ──────────────────────────────────
|
||||
* 本函数是 register_setting() 的 sanitize_callback,WP 会把
|
||||
* 它的返回值直接写进 options 表。所以**返回旧值就等于拒绝本次
|
||||
* 保存**(新值一个字段都不落库),不需要额外抛异常或 unset。
|
||||
*
|
||||
* 为什么是"整单拒绝"而不是"只把开关取消":用户明确选了这条路
|
||||
* (选项一「整个保存被拒绝」)。附带效果是同一次里改的其它设置
|
||||
* 也会一起作废 —— 这是有意的:提交了一个不合法的表单,就不该
|
||||
* 让其中一部分悄悄生效,否则用户会以为"我保存成功了"。
|
||||
*
|
||||
* ── 为什么用 $_POST 而不是 $input ──────────────────────
|
||||
* $input 已经过 WP 的 wp_unslash,但复选框"没勾"时这个键
|
||||
* **根本不会出现在 POST 里**(浏览器不提交未勾选的 checkbox)。
|
||||
* 而这里的 $input 是同名过滤器链上拿到的数组,语义一致;
|
||||
* 用 $input 就够,且不依赖具体表单字段名。$clean 里已经有
|
||||
* 经过 of_sanitize_checkbox() 的值,直接用它最准。
|
||||
*/
|
||||
if ( function_exists( 'yang_cdn_check_config' ) ) {
|
||||
$cdn_enable = isset( $clean['cdn_enable'] ) ? $clean['cdn_enable'] : false;
|
||||
$cdn_url = isset( $clean['cdn_url'] ) ? $clean['cdn_url'] : '';
|
||||
$cdn_err = yang_cdn_check_config( $cdn_enable, $cdn_url );
|
||||
|
||||
if ( $cdn_err !== '' ) {
|
||||
/*
|
||||
* ⚠️ 这里**绝对不能**调 update_option() 把旧值写回去。
|
||||
* 本函数就在 sanitize_option_kratos 过滤器上,
|
||||
* update_option() 会再触发一次同名过滤器 ⇒ 无限递归
|
||||
* ⇒ 吃爆内存(3.2.11 的事故,报错落在区块解析器上,
|
||||
* 看那个报错会完全找错方向)。见下面 sendmail 分支的注释。
|
||||
*
|
||||
* 正确做法就是"返回旧值":WP 自己会把它写进库,
|
||||
* 结果与"没保存"等价。
|
||||
*/
|
||||
add_settings_error(
|
||||
'options-framework',
|
||||
'cdn_needs_url',
|
||||
__( '未保存:', 'kratos' ) . $cdn_err,
|
||||
'error'
|
||||
);
|
||||
/*
|
||||
* 「保存成功」那条提示不用手动清:本函数在校验分支里
|
||||
* 直接 return,后面的 do_action('optionsframework_after_validate')
|
||||
* 根本不会执行,所以它不会被加进 settings_errors。
|
||||
* 若改成"清一下",反而是多余动作,会让人误以为
|
||||
* 两条提示都会出现、需要手工压掉。
|
||||
*/
|
||||
|
||||
$current = get_option( 'kratos' );
|
||||
return is_array( $current ) ? $current : array();
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $_POST['sendmail'] ) ) {
|
||||
/*
|
||||
* 测试发信要让「这一批新配置」立刻生效,但**绝对不能**
|
||||
@@ -340,6 +410,34 @@ class Options_Framework_Admin {
|
||||
$GLOBALS['__yang_sendmail_result'] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 进入设置页时的状态提示
|
||||
*
|
||||
* ── 为什么需要在"进页面"时就提示 ────────────────────────────
|
||||
* 保存时的拦截只在用户点保存那一刻生效。而"勾了启用但地址空"
|
||||
* 这个状态还有另一种来源:**老站点从 3.2.34 升级上来**。
|
||||
* 3.2.34 没有这个复选框,升级后如果用户清空过地址、又一直没动
|
||||
* 过这个开关,他就是"看起来已启用、实际没生效"的状态。
|
||||
* 这种人不会点保存(他没想改设置),所以只靠保存拦截永远救不到他。
|
||||
*
|
||||
* 提示放在 options_page() 渲染之前(本函数挂在 admin_init),
|
||||
* add_settings_error 会随 settings_errors() 一起显示。
|
||||
*/
|
||||
function yang_cdn_config_notice() {
|
||||
if ( ! function_exists( 'yang_cdn_missing_url' ) ) {
|
||||
return;
|
||||
}
|
||||
if ( ! yang_cdn_missing_url() ) {
|
||||
return;
|
||||
}
|
||||
add_settings_error(
|
||||
'options-framework',
|
||||
'cdn_missing_url',
|
||||
__( '「启用 CDN 加速」是勾选状态,但 CDN 地址是空的,功能当前<b>没有生效</b>(前台与关闭时完全一样)。请填写 CDN 地址,或者取消勾选这个开关。', 'kratos' ),
|
||||
'error'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display message when options have been saved
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user