From ec815d42822236952fc3477ebc5336e1a2a37acd Mon Sep 17 00:00:00 2001 From: laoyang Date: Fri, 6 Nov 2026 20:11:24 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=84=E8=AE=BA=E9=80=9A=E7=9F=A5=E9=82=AE?= =?UTF-8?q?=E4=BB=B6=E6=97=A0=E6=A0=B7=E5=BC=8F=EF=BC=9A=E6=8E=A5=E7=AE=A1?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E9=80=9A=E7=9F=A5=E6=AD=A3=E6=96=87=20#39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 卸载 wpDiscuz 后,评论通知回落到核心 wp_notify_postauthor / wp_notify_moderator。theme-mail.php 只接管了通道(SMTP、From), 并把 Content-Type 强改成 text/html,而正文仍是核心拼的纯文本, 客户端按 HTML 渲染 ⇒ 换行丢、链接变裸地址。 新增 inc/theme-mail-core.php,挂 comment_notification_text / comment_moderation_text 两个过滤器,把正文换成主题模板。这是核心 自己提供的扩展点,不改核心文件,删掉即回退。 模板新增 links 参数,把 通过/回收站/垃圾 渲染成一行文字链接 (并排三按钮在手机上必然换行、高度不齐)。 版本 4.2.1 -> 4.2.2 --- functions.php | 5 + inc/theme-mail-core.php | 248 ++++++++++++++++++++++++++++++++++++ inc/theme-mail-template.php | 28 ++++ style.css | 2 +- 4 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 inc/theme-mail-core.php diff --git a/functions.php b/functions.php index 7b0f50e..6c11ae5 100644 --- a/functions.php +++ b/functions.php @@ -95,6 +95,11 @@ require get_template_directory() . '/inc/theme-mail-template.php'; // 邮件治理:统一接管发信通道、去重、关掉重复通知 require get_template_directory() . '/inc/theme-mail.php'; +// 核心评论通知正文接管:挂 comment_notification_text / comment_moderation_text +// 两个过滤器。不接管的话,核心那封纯文本会被 Content-Type: text/html 硬渲染, +// 收件人看到的是一堆没有样式的裸地址(3.2.18 卸载 wpDiscuz 后才暴露)。 +require get_template_directory() . '/inc/theme-mail-core.php'; + // SMTP 配置(连通性相关,实际接管在 theme-mail.php) require get_template_directory() . '/inc/theme-smtp.php'; diff --git a/inc/theme-mail-core.php b/inc/theme-mail-core.php new file mode 100644 index 0000000..df0ae00 --- /dev/null +++ b/inc/theme-mail-core.php @@ -0,0 +1,248 @@ + + * @license MIT License + */ + +if (!defined('ABSPATH')) { + exit; +} + +/** + * 取评论对应的文章标题 + * + * 文章被删掉时 get_the_title() 返回空串,邮件里就会出现《》, + * 比直接说「文章已删除」更难懂。 + */ +function yang_mail_core_post_title($post_id) +{ + $post = get_post($post_id); + if (!$post) { + return __('(文章已删除)', 'kratos'); + } + $t = get_the_title($post); + return $t !== '' ? $t : __('(无标题)', 'kratos'); +} + +/** + * 后台评论操作链接 + * + * 核心给的 approve / spam / trash 是三个裸 URL,这里做成模板里的一行 + * 文字链接。为什么不做成三个并排按钮:邮件里并排三个按钮在手机上 + * 必然换行、高度不齐,看起来像渲染出错;而且这些是后台管理动作, + * 不该和主按钮抢视觉权重。 + * + * @param int $comment_id + * @param bool $with_approve 已发布的评论不需要「通过」 + * @return array + */ +function yang_mail_core_action_links($comment_id, $with_approve = false) +{ + $id = (int) $comment_id; + $links = array(); + + if ($with_approve) { + $links[] = array( + 'text' => __('通过审核', 'kratos'), + 'url' => admin_url("comment.php?action=approve&c={$id}#wpbody-content"), + ); + } + + if (EMPTY_TRASH_DAYS) { + $links[] = array( + 'text' => __('移至回收站', 'kratos'), + 'url' => admin_url("comment.php?action=trash&c={$id}#wpbody-content"), + ); + } else { + $links[] = array( + 'text' => __('永久删除', 'kratos'), + 'url' => admin_url("comment.php?action=delete&c={$id}#wpbody-content"), + ); + } + + $links[] = array( + 'text' => __('标记为垃圾', 'kratos'), + 'url' => admin_url("comment.php?action=spam&c={$id}#wpbody-content"), + ); + + return $links; +} + +/** + * 把评论通知(有新评论 → 文章作者)渲染成主题模板 + * + * @param string $text 核心生成的纯文本(仅在参数非法时原样返回) + * @param string|int $comment_id + * @return string + */ +function yang_mail_core_render_comment_notify($text, $comment_id) +{ + if (!yang_mail_smtp_ready()) { + return $text; + } + + $comment = get_comment($comment_id); + if (!($comment instanceof WP_Comment)) { + return $text; + } + + // 引用 / Pingback 不是评论,字段结构不同,不套模板 + if ($comment->comment_type === 'trackback' || $comment->comment_type === 'pingback') { + return $text; + } + + $title = yang_mail_core_post_title($comment->comment_post_ID); + $author = $comment->comment_author !== '' ? $comment->comment_author : __('匿名访客', 'kratos'); + + $rows = array( + array('label' => __('文章', 'kratos'), 'value' => $title), + array('label' => __('评论者', 'kratos'), 'value' => $author, 'strong' => true), + ); + + if ($comment->comment_author_email !== '') { + $rows[] = array('label' => __('邮箱', 'kratos'), 'value' => $comment->comment_author_email); + } + if ($comment->comment_author_url !== '') { + $rows[] = array('label' => __('网址', 'kratos'), 'value' => $comment->comment_author_url); + } + if ($comment->comment_author_IP !== '') { + $rows[] = array('label' => __('IP 地址', 'kratos'), 'value' => $comment->comment_author_IP); + } + $rows[] = array('label' => __('时间', 'kratos'), 'value' => mysql2date('Y-m-d H:i', $comment->comment_date)); + + return yang_mail_render(array( + 'title' => sprintf(__('%s · 新评论', 'kratos'), get_bloginfo('name')), + 'preheader' => sprintf(__('%s 在《%s》下发表了评论。', 'kratos'), $author, $title), + 'badge' => __('新评论', 'kratos'), + 'heading' => __('文章有新评论', 'kratos'), + 'intro' => sprintf(__('《%s》收到了一条新评论。', 'kratos'), $title), + 'quotes' => array( + array( + 'label' => sprintf(__('%s 说', 'kratos'), $author), + 'content' => yang_mail_text($comment->comment_content, 1200), + 'meta' => mysql2date('Y-m-d H:i', $comment->comment_date), + ), + ), + 'rows' => $rows, + 'cta_text' => __('查看评论', 'kratos'), + 'cta_url' => get_comment_link($comment), + 'links' => yang_mail_core_action_links($comment->comment_ID, false), + 'note' => __('你收到这封邮件,是因为你是这篇文章的作者。', 'kratos'), + )); +} +add_filter('comment_notification_text', 'yang_mail_core_render_comment_notify', 20, 2); + +/** + * 把审核通知(有待审评论 → 管理员)渲染成主题模板 + * + * 内容与上面高度重合,差别只有:徽标是「待审核」、主按钮去审核面板、 + * 操作行多一个「通过审核」。合并成一个函数要靠一堆 if 分叉, + * 不如分开写清楚。 + * + * @param string $text + * @param string|int $comment_id + * @return string + */ +function yang_mail_core_render_moderation($text, $comment_id) +{ + if (!yang_mail_smtp_ready()) { + return $text; + } + + $comment = get_comment($comment_id); + if (!($comment instanceof WP_Comment)) { + return $text; + } + + if ($comment->comment_type === 'trackback' || $comment->comment_type === 'pingback') { + return $text; + } + + $title = yang_mail_core_post_title($comment->comment_post_ID); + $author = $comment->comment_author !== '' ? $comment->comment_author : __('匿名访客', 'kratos'); + + $rows = array( + array('label' => __('文章', 'kratos'), 'value' => $title), + array('label' => __('评论者', 'kratos'), 'value' => $author, 'strong' => true), + ); + + if ($comment->comment_author_email !== '') { + $rows[] = array('label' => __('邮箱', 'kratos'), 'value' => $comment->comment_author_email); + } + if ($comment->comment_author_url !== '') { + $rows[] = array('label' => __('网址', 'kratos'), 'value' => $comment->comment_author_url); + } + if ($comment->comment_author_IP !== '') { + $rows[] = array('label' => __('IP 地址', 'kratos'), 'value' => $comment->comment_author_IP); + } + $rows[] = array('label' => __('时间', 'kratos'), 'value' => mysql2date('Y-m-d H:i', $comment->comment_date)); + + return yang_mail_render(array( + 'title' => sprintf(__('%s · 待审核评论', 'kratos'), get_bloginfo('name')), + 'preheader' => sprintf(__('%s 在《%s》下的评论等待审核。', 'kratos'), $author, $title), + 'badge' => __('待审核', 'kratos'), + 'heading' => __('有一条评论等待审核', 'kratos'), + 'intro' => sprintf(__('《%s》收到了新评论,需要你确认后才公开显示。', 'kratos'), $title), + 'quotes' => array( + array( + 'label' => sprintf(__('%s 说', 'kratos'), $author), + 'content' => yang_mail_text($comment->comment_content, 1200), + 'meta' => mysql2date('Y-m-d H:i', $comment->comment_date), + ), + ), + 'rows' => $rows, + 'cta_text' => __('去后台审核', 'kratos'), + 'cta_url' => admin_url('edit-comments.php?comment_status=moderated#wpbody-content'), + 'links' => yang_mail_core_action_links($comment->comment_ID, true), + 'note' => __('这是评论审核提醒,处理完即可忽略。', 'kratos'), + )); +} +add_filter('comment_moderation_text', 'yang_mail_core_render_moderation', 20, 2); \ No newline at end of file diff --git a/inc/theme-mail-template.php b/inc/theme-mail-template.php index 9fdd7f7..2bb68f4 100644 --- a/inc/theme-mail-template.php +++ b/inc/theme-mail-template.php @@ -750,6 +750,9 @@ function yang_mail_button($text, $url, $bg = null, $fg = null) * @type string $cta_url 按钮链接 * @type string $note 底部提示(纯文本) * @type string $badge 顶部小标签,如「新评论」 + * @type array $links 次要操作链接,每项 array('text'=>, 'url'=>)。 + * 用于后台管理动作(通过/回收站/垃圾),渲染成一行文字链接, + * 不做成并排按钮:手机宽度下三个按钮必然换行、高度不齐。 * } * @return string 完整 HTML */ @@ -767,6 +770,7 @@ function yang_mail_render($args) 'cta_url' => '', 'note' => '', 'badge' => '', + 'links' => array(), // 次要操作链接 array('text'=>, 'url'=>),渲染成一行文字链接 )); /* 统一成 $quoteList: @@ -973,6 +977,30 @@ function yang_mail_render($args) + + +
+ $lk): + if (empty($lk['text']) || empty($lk['url'])) { + continue; + } +?> + · '; + } + endforeach; +?> +
+ +
diff --git a/style.css b/style.css index b590c87..04512a8 100644 --- a/style.css +++ b/style.css @@ -1,7 +1,7 @@ /* Theme Name: Kratos_Yang Text Domain: kratos_Yang -Version: 4.2.1 +Version: 4.2.2 Requires PHP: 7.0 Description: 这是一个Kratos主题的分支版本,用来增加一些定制化功能。 Tags: 博客, 双栏, 响应式, 自定义背景, 自定义颜色, 自定义图标, 自定义菜单, 特色图像, 收录优化, 邮件中心, 主题选项, 小工具, 文章置顶, 无障碍友好