From 13a0800f13a3706f8003cfa959b8babcd940660f Mon Sep 17 00:00:00 2001 From: nanhaoluo <3075912108@qq.com> Date: Tue, 20 Jan 2026 16:13:52 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=81=A2=E5=A4=8D=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- email-templates/base.php | 14 +- email-templates/feedback-notify.php | 311 ++++++++++++++++++++++++++++ 2 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 email-templates/feedback-notify.php diff --git a/email-templates/base.php b/email-templates/base.php index 5d494f3..5d5227a 100644 --- a/email-templates/base.php +++ b/email-templates/base.php @@ -314,8 +314,20 @@ function argon_replace_placeholders($template, $vars, $escape = false) { $vars = array_merge($global_vars, $vars); + // 处理条件语句 {{#if variable}}...{{/if}} + $template = preg_replace_callback('/\{\{#if\s+(\w+)\}\}(.*?)\{\{\/if\}\}/s', function($matches) use ($vars) { + $var_name = $matches[1]; + $content = $matches[2]; + // 如果变量存在且不为空,返回内容,否则返回空字符串 + if (isset($vars[$var_name]) && !empty($vars[$var_name])) { + return $content; + } + return ''; + }, $template); + + // 替换普通占位符 foreach ($vars as $key => $value) { - if ($escape && !in_array($key, array('theme_color', 'blog_url', 'post_url', 'comment_url', 'reset_url', 'login_url'))) { + if ($escape && !in_array($key, array('theme_color', 'blog_url', 'post_url', 'comment_url', 'reset_url', 'login_url', 'feedback_manage_url', 'feedback_view_url'))) { $value = esc_html($value); } $template = str_replace('{{' . $key . '}}', $value, $template); diff --git a/email-templates/feedback-notify.php b/email-templates/feedback-notify.php new file mode 100644 index 0000000..9153251 --- /dev/null +++ b/email-templates/feedback-notify.php @@ -0,0 +1,311 @@ + __('新反馈通知', 'argon'), + 'description' => __('收到新反馈时发送给管理员', 'argon'), + 'default_subject' => '[{{blog_name}}] 收到新的问题反馈', + 'default_content' => '
{{feedback_name}} ({{feedback_email}}) 提交了一条{{feedback_type_label}}:
+{{#if feedback_title}} +{{feedback_title}}
+{{/if}} +{{feedback_content}}
+提交时间:{{feedback_time}}
++ 前往管理 +
', + 'placeholders' => array( + 'blog_name' => __('博客名称', 'argon'), + 'feedback_name' => __('反馈者昵称', 'argon'), + 'feedback_email' => __('反馈者邮箱', 'argon'), + 'feedback_title' => __('反馈标题', 'argon'), + 'feedback_content' => __('反馈内容', 'argon'), + 'feedback_type_label' => __('反馈类型', 'argon'), + 'feedback_time' => __('提交时间', 'argon'), + 'feedback_manage_url' => __('管理链接', 'argon'), + 'feedback_images' => __('附件图片(HTML)', 'argon'), + 'theme_color' => __('主题色', 'argon'), + ), + ); + + $types['feedback_reply'] = array( + 'name' => __('反馈回复通知', 'argon'), + 'description' => __('反馈收到回复时发送给用户', 'argon'), + 'default_subject' => '[{{blog_name}}] 您的反馈已收到回复', + 'default_content' => '您好 {{feedback_name}}!
+您提交的反馈:
+{{feedback_title_or_content}}
+博主回复了您:
+{{reply_content}}
++ 查看详情 +
+此链接为您的专属链接,请妥善保管。
', + 'placeholders' => array( + 'blog_name' => __('博客名称', 'argon'), + 'feedback_name' => __('反馈者昵称', 'argon'), + 'feedback_title_or_content' => __('反馈标题或内容', 'argon'), + 'reply_content' => __('回复内容', 'argon'), + 'feedback_view_url' => __('查看链接(授权链接)', 'argon'), + 'theme_color' => __('主题色', 'argon'), + ), + ); + + $types['feedback_resolved'] = array( + 'name' => __('反馈完结通知', 'argon'), + 'description' => __('反馈被标记为已解决时发送给用户', 'argon'), + 'default_subject' => '[{{blog_name}}] 您的反馈已处理完成', + 'default_content' => '您好 {{feedback_name}}!
+您提交的反馈「{{feedback_title_or_content}}」已被标记为已解决。
+{{#if reply_content}} +博主的回复:
+{{reply_content}}
+感谢您的反馈,它帮助我们变得更好!
++ 查看详情 +
+此链接可直接访问
', + 'placeholders' => array( + 'blog_name' => __('博客名称', 'argon'), + 'feedback_name' => __('反馈者昵称', 'argon'), + 'feedback_title_or_content' => __('反馈标题或内容', 'argon'), + 'reply_content' => __('回复内容(如有)', 'argon'), + 'feedback_view_url' => __('查看链接(授权链接)', 'argon'), + 'theme_color' => __('主题色', 'argon'), + ), + ); + + $types['feedback_reply_append'] = array( + 'name' => __('反馈留言追加通知', 'argon'), + 'description' => __('已完结的反馈收到新留言时发送给用户', 'argon'), + 'default_subject' => '[{{blog_name}}] 您的反馈收到新留言', + 'default_content' => '您好 {{feedback_name}}!
+您已完结的反馈「{{feedback_title_or_content}}」收到了新的留言:
+{{reply_content}}
++ 查看详情 +
+此链接为您的专属链接,请妥善保管。
', + 'placeholders' => array( + 'blog_name' => __('博客名称', 'argon'), + 'feedback_name' => __('反馈者昵称', 'argon'), + 'feedback_title_or_content' => __('反馈标题或内容', 'argon'), + 'reply_content' => __('新留言内容', 'argon'), + 'feedback_view_url' => __('查看链接(授权链接)', 'argon'), + 'theme_color' => __('主题色', 'argon'), + ), + ); + + return $types; +} + +/** + * 生成反馈授权 token + * + * @param string $feedback_id 反馈 ID + * @return string 授权 token + */ +function argon_generate_feedback_token($feedback_id) { + $secret = wp_salt('auth'); + return substr(hash('sha256', $feedback_id . $secret), 0, 32); +} + +/** + * 验证反馈授权 token + * + * @param string $feedback_id 反馈 ID + * @param string $token 授权 token + * @return bool 是否有效 + */ +function argon_verify_feedback_token($feedback_id, $token) { + return hash_equals(argon_generate_feedback_token($feedback_id), $token); +} + +/** + * 获取反馈授权查看链接 + * + * @param string $feedback_id 反馈 ID + * @return string 授权链接 + */ +function argon_get_feedback_auth_url($feedback_id) { + $token = argon_generate_feedback_token($feedback_id); + $feedback_page_url = get_template_directory_uri(); + // 使用主题目录下的 feedback.php + $base_url = home_url('/') . '?argon_feedback_view=1'; + return add_query_arg(array( + 'id' => $feedback_id, + 'token' => $token + ), $base_url); +} + +/** + * 发送新反馈通知邮件给管理员 + * + * @param array $feedback 反馈数据 + * @return bool 发送是否成功 + */ +function argon_send_feedback_new_notify($feedback) { + // 检查是否启用邮件通知 + if (get_option('argon_feedback_notify_admin', 'true') !== 'true') { + return false; + } + + $type_labels = array( + 'bug' => __('Bug 报告', 'argon'), + 'suggestion' => __('建议', 'argon'), + 'question' => __('问题咨询', 'argon'), + 'other' => __('其他反馈', 'argon') + ); + + // 邮件中不显示图片,仅提示数量 + $images_html = ''; + if (!empty($feedback['images']) && is_array($feedback['images'])) { + $count = count($feedback['images']); + $images_html = '' . sprintf(__('包含 %d 张图片(请在管理后台查看)', 'argon'), $count) . '
'; + } + + $vars = array( + 'feedback_name' => $feedback['name'], + 'feedback_email' => $feedback['email'], + 'feedback_title' => $feedback['title'], + 'feedback_content' => $feedback['content'], + 'feedback_type_label' => isset($type_labels[$feedback['type']]) ? $type_labels[$feedback['type']] : $type_labels['other'], + 'feedback_time' => date_i18n(get_option('date_format') . ' ' . get_option('time_format'), $feedback['created_at']), + 'feedback_manage_url' => home_url('/') . '?argon_feedback_view=1', + 'feedback_images' => $images_html, + ); + + $admin_email = get_option('admin_email'); + return argon_send_email($admin_email, 'feedback_new', $vars); +} + +/** + * 发送反馈回复通知邮件给用户 + * + * @param array $feedback 反馈数据 + * @param string $reply 回复内容 + * @return bool 发送是否成功 + */ +function argon_send_feedback_reply_notify($feedback, $reply) { + if (empty($feedback['email']) || empty($reply)) { + return false; + } + + // 检查是否启用邮件通知 + if (get_option('argon_feedback_notify_user', 'true') !== 'true') { + return false; + } + + $title_or_content = !empty($feedback['title']) ? $feedback['title'] : mb_substr($feedback['content'], 0, 50) . '...'; + + $vars = array( + 'feedback_name' => $feedback['name'], + 'feedback_title_or_content' => $title_or_content, + 'reply_content' => $reply, + 'feedback_view_url' => argon_get_feedback_auth_url($feedback['id']), + ); + + return argon_send_email($feedback['email'], 'feedback_reply', $vars); +} + +/** + * 发送反馈完结通知邮件给用户 + * + * @param array $feedback 反馈数据 + * @return bool 发送是否成功 + */ +function argon_send_feedback_resolved_notify($feedback) { + if (empty($feedback['email'])) { + return false; + } + + // 检查是否启用邮件通知 + if (get_option('argon_feedback_notify_user', 'true') !== 'true') { + return false; + } + + $title_or_content = !empty($feedback['title']) ? $feedback['title'] : mb_substr($feedback['content'], 0, 50) . '...'; + + // 获取最后一条非私密留言 + $last_reply = ''; + $replies = $feedback['replies'] ?? []; + if (empty($replies) && !empty($feedback['reply'])) { + $last_reply = $feedback['reply']; + } else { + for ($i = count($replies) - 1; $i >= 0; $i--) { + if (empty($replies[$i]['is_private'])) { + $last_reply = $replies[$i]['content']; + break; + } + } + } + + $vars = array( + 'feedback_name' => $feedback['name'], + 'feedback_title_or_content' => $title_or_content, + 'reply_content' => $last_reply, + 'feedback_view_url' => argon_get_feedback_auth_url($feedback['id']), + ); + + return argon_send_email($feedback['email'], 'feedback_resolved', $vars); +} + +/** + * 发送反馈留言追加通知邮件给用户 + * + * @param array $feedback 反馈数据 + * @param string $reply 新留言内容 + * @return bool 发送是否成功 + */ +function argon_send_feedback_reply_append_notify($feedback, $reply) { + if (empty($feedback['email']) || empty($reply)) { + return false; + } + + // 检查是否启用邮件通知 + if (get_option('argon_feedback_notify_user', 'true') !== 'true') { + return false; + } + + $title_or_content = !empty($feedback['title']) ? $feedback['title'] : mb_substr($feedback['content'], 0, 50) . '...'; + + $vars = array( + 'feedback_name' => $feedback['name'], + 'feedback_title_or_content' => $title_or_content, + 'reply_content' => $reply, + 'feedback_view_url' => argon_get_feedback_auth_url($feedback['id']), + ); + + return argon_send_email($feedback['email'], 'feedback_reply_append', $vars); +}