3.2.11 后台「测试邮件」改走主题模板,并修发信早于落库

两个问题叠在一起,都不报错,只是「测了等于没测」:

1. 按钮发的是纯文本
   validate_options() 里 isset($_POST['sendmail']) 那个分支只有一句裸
   wp_mail(),正文是「恭喜您 SMTP 邮件服务配置成功!」。于是点测试收到的
   东西和真实评论通知(HTML 模板)完全不同,没法用它验收版式。
   主题里 yang_mail_send_test() 本来就是干这件事的,但全仓库零调用点 ——
   注释写着「后台测试按钮走这条」,实际上从没接上线。

2. 发信发生在配置落库之前
   validate_options() 是 register_setting 的回调,返回值之后才由 WP
   写进数据库。在分支里直接发信,主题配 PHPMailer 时读 kratos_option()
   拿到的还是上一次保存的主机/账号/密码。刚改完 SMTP 密码点测试,
   测的是旧密码,表现成「明明填对了却发不出去」。

改法:
- 分支里先 update_option('kratos', $clean) 再调 yang_send_test_mail()
- yang_send_test_mail() 优先调主题的 yang_mail_send_test();
  主题被换掉时退回原来的纯文本,不能因此白屏
- send_mail_notice() 从「一律发送完成」改成三态:WP_Error / wp_mail
  返回 false / 成功,前两者用 error 样式。原来密码错了也显示成功,
  用户会去邮箱里干等。

assertions: run_tests 95 → 104 条(新增 2k 组 8 条 + 1 条)
- sendmail 分支确实调用主题发信函数、确实先落库
- 落库位置在发信位置之前(判顺序,不判有没有)
- 分支里没有裸 wp_mail
- 发信函数对主题缺失做了兜底
- 提示语分三态,两类失败都用 error 样式

falsify 22 → 24 条:
- 注入「先发信后落库」⇒ 变红(这条一开始是假绿:判据比的是注释里
  那两个词谁先出现,注释里 update_option 和函数名都在,恒真。
  改成先剥注释再比代码里的位置)
- 注入「退回裸 wp_mail」⇒ 变红

顺带修了 falsify 的一个基础设施坑:options-framework 那批文件在工作区
是 CRLF,锚点里写 \n 对多行内容恒不匹配,报的是「命中 0 次」,
很像锚点选错了。inject() 现在先试原样、不中再把 \n 换 \r\n 重试一次。

全量 12 组 / 506 条断言全绿。
This commit is contained in:
2026-10-23 18:28:53 +08:00
parent 6f50533e8e
commit 9a053169e9
2 changed files with 64 additions and 3 deletions
@@ -254,7 +254,19 @@ class Options_Framework_Admin {
} }
if ( isset( $_POST['sendmail'] ) ) { if ( isset( $_POST['sendmail'] ) ) {
wp_mail( get_bloginfo( 'admin_email' ) ,__('[测试]邮件服务配置成功', 'kratos'),__('恭喜您 SMTP 邮件服务配置成功!', 'kratos')); /*
* 测试发信必须先落库再发。
*
* 这个函数是 register_setting 的回调,返回值**之后**才会被
* update_option() 写进数据库。如果在这里直接 wp_mail(),
* 主题配置 PHPMailer 时读 kratos_option() 拿到的还是**上一次**保存的
* 主机/账号/密码 —— 刚改完配置点测试,测的其实是旧配置,
* 用户会看到"明明填对了却发不出去"或"改了密码还能发"这种怪现象。
*/
update_option( 'kratos', $clean );
$this->yang_send_test_mail( $clean );
do_action( 'optionsframework_after_sendmail', $clean ); do_action( 'optionsframework_after_sendmail', $clean );
return $clean; return $clean;
} else { } else {
@@ -263,6 +275,28 @@ class Options_Framework_Admin {
} }
} }
/**
* 发测试邮件,走主题模板
*
* 原来这里是一句裸 wp_mail(),正文只有一行纯文本 —— 点「测试邮件」
* 收到的样子和真实评论通知(HTML 模板)完全不同,等于没法用它验收版式。
* 主题里早有 yang_mail_send_test() 专门干这件事,但一直没接线,
* 所以优先调它;主题被换掉或不完全时退回原样,不能因此白屏。
*/
private function yang_send_test_mail( $clean )
{
$to = get_bloginfo( 'admin_email' );
if ( function_exists( 'yang_mail_send_test' ) ) {
$r = yang_mail_send_test( $to );
$GLOBALS['__yang_sendmail_result'] = $r;
return;
}
wp_mail( $to, __( '[测试]邮件服务配置成功', 'kratos' ), __( '恭喜您 SMTP 邮件服务配置成功!', 'kratos' ) );
$GLOBALS['__yang_sendmail_result'] = null;
}
/** /**
* Display message when options have been saved * Display message when options have been saved
*/ */
@@ -270,8 +304,35 @@ class Options_Framework_Admin {
add_settings_error( 'options-framework', 'save_options', __( '保存成功', 'kratos' ), 'updated fade' ); add_settings_error( 'options-framework', 'save_options', __( '保存成功', 'kratos' ), 'updated fade' );
} }
/**
* 测试邮件的提示
*
* 原来不管发没发出去都显示「发送完成」—— SMTP 密码填错时用户也看到
* "成功",然后去邮箱里干等。现在按真实返回值分三态:成功 / 失败 / 地址不合法。
*/
function send_mail_notice() { function send_mail_notice() {
add_settings_error( 'options-framework', 'send_mail', __( '发送完成,请留意邮箱:' . get_bloginfo( 'admin_email' ), 'kratos' ), 'updated fade' ); $to = get_bloginfo( 'admin_email' );
$r = isset( $GLOBALS['__yang_sendmail_result'] ) ? $GLOBALS['__yang_sendmail_result'] : null;
if ( is_wp_error( $r ) ) {
add_settings_error(
'options-framework', 'send_mail',
sprintf( __( '测试邮件未发出:%s', 'kratos' ), $r->get_error_message() ),
'error fade'
);
return;
}
if ( $r === false ) {
add_settings_error(
'options-framework', 'send_mail',
__( '测试邮件发送失败,请检查服务器地址、端口、加密方式与密码。', 'kratos' ),
'error fade'
);
return;
}
add_settings_error( 'options-framework', 'send_mail', sprintf( __( '测试邮件已发出,请查收:%s(若没收到请先看垃圾箱)', 'kratos' ), $to ), 'updated fade' );
} }
/** /**
+1 -1
View File
@@ -1,7 +1,7 @@
/* /*
Theme Name: Kratos_Yang Theme Name: Kratos_Yang
Text Domain: kratos_Yang Text Domain: kratos_Yang
Version: 3.2.10 Version: 3.2.11
Requires PHP: 7.0 Requires PHP: 7.0
Description: 这是一个Kratos主题的分支版本,用来增加一些定制化功能。 Description: 这是一个Kratos主题的分支版本,用来增加一些定制化功能。
Tags: 博客, 双栏, 响应式, 自定义背景, 自定义颜色, 自定义图标, 自定义菜单, 特色图像, 收录优化, 邮件中心, 主题选项, 小工具, 文章置顶, 无障碍友好 Tags: 博客, 双栏, 响应式, 自定义背景, 自定义颜色, 自定义图标, 自定义菜单, 特色图像, 收录优化, 邮件中心, 主题选项, 小工具, 文章置顶, 无障碍友好