fix(email): complete mail settings and templates

This commit is contained in:
kate522 committed 2026-09-04 12:06:42 +08:00
1 parent 4f8ab94fac
commit 4833053a5c
29 files changed
+716 -426

No files matched your search

+4 -31
View File
@@ -23,12 +23,6 @@ class GlobalController extends ControllerBase {
* Register all routes for the global domain.
*/
public function register_routes(): void {
// Email / SMTP
register_rest_route(self::API_NAMESPACE, '/settings/mail', [
'methods' => ['GET', 'POST'],
'callback' => [$this, 'rest_handle_mail'],
'permission_callback' => [$this, 'check_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/mail/test', [
'methods' => 'POST',
'callback' => [$this, 'rest_test_mail'],
@@ -175,30 +169,6 @@ class GlobalController extends ControllerBase {
return $this->success(['message' => 'CMS 功能已保存', 'cms_features' => \AKSRT\Settings\Settings::get_cms_features()]);
}
public function rest_handle_mail(\WP_REST_Request $request): \WP_REST_Response {
$option_key = 'aksrt_mail_config';
if ($request->get_method() === 'GET') {
$config = get_option($option_key, [
'smtp_host' => '',
'smtp_port' => 465,
'smtp_user' => '',
'smtp_pass' => '',
'smtp_secure' => 'ssl',
'from_email' => '',
'from_name' => '',
]);
return $this->success(['data' => $config, 'code' => 'success']);
}
$params = $this->get_json_params($request);
$current = get_option($option_key, []);
$merged = array_merge(is_array($current) ? $current : [], $params);
update_option($option_key, $merged);
return $this->success(['message' => '邮件配置已保存', 'code' => 'success']);
}
public function rest_test_mail(\WP_REST_Request $request): \WP_REST_Response {
$params = $this->get_json_params($request);
$to = sanitize_email($params['to'] ?? '');
@@ -206,7 +176,9 @@ class GlobalController extends ControllerBase {
return $this->error(__('请输入有效的邮箱地址', 'aksrt'));
}
$sent = wp_mail($to, __('AKSRT 邮件测试', 'aksrt'), __('如果你收到这封邮件,说明 SMTP 配置正确。', 'aksrt'));
$sent = class_exists('\\AKSRT\\Settings\\Mail')
? \AKSRT\Settings\Mail::send_test_email($to)
: false;
if ($sent) {
return $this->success(['message' => '测试邮件已发送']);
}
@@ -388,6 +360,7 @@ class GlobalController extends ControllerBase {
return ($a['sort_order'] ?? 0) <=> ($b['sort_order'] ?? 0);
});
update_option('aksrt_friend_links', $links);
do_action('aksrt_friend_link_submitted', $new_link);
return rest_ensure_response(['code' => 'success', 'data' => $new_link, 'message' => __('Friend link added.', 'aksrt')]);
}
+1 -58
View File
@@ -369,64 +369,7 @@ class GlobalSchema {
]],
],
],
'email' => [
'key' => 'email',
'title' => '邮件事件',
'version' => '2.0.0',
'option_key' => 'aksrt_settings',
'groups' => [
['key' => 'global', 'title' => '全局设置', 'fields' => [
['key' => 'email_footer_text', 'label' => '邮件页脚文字', 'type' => 'textarea', 'default' => ''],
['key' => 'email_site_branding', 'label' => '显示站点品牌', 'type' => 'switch', 'default' => true],
['key' => 'email_template_mode', 'label' => '邮件格式', 'type' => 'radio', 'default' => 'plain', 'options' => [
['label' => '纯文本', 'value' => 'plain'],
['label' => 'HTML', 'value' => 'html'],
]],
]],
['key' => 'branding', 'title' => '邮件品牌', 'fields' => [
['key' => 'mail_showname', 'label' => '发件人名称', 'type' => 'input', 'default' => '', 'help' => '覆盖系统默认发件人名称'],
['key' => 'mail_title_prefix', 'label' => '主题前缀', 'type' => 'input', 'default' => '', 'help' => '自动添加在所有邮件主题前面,如【站点名】'],
['key' => 'mail_description', 'label' => '邮件底部说明', 'type' => 'textarea', 'default' => '', 'help' => '附加在邮件页脚文字之后,留空不显示'],
['key' => 'mail_more_content', 'label' => '邮件附加内容', 'type' => 'textarea', 'default' => '', 'help' => '附加在邮件内容末尾的补充说明'],
]],
['key' => 'reg_verify_link', 'title' => '注册验证链接', 'fields' => [
['key' => 'email_reg_verify_link_enabled', 'label' => '启用', 'type' => 'switch', 'default' => true],
['key' => 'email_reg_verify_link_subject', 'label' => '主题', 'type' => 'input', 'default' => ''],
['key' => 'email_reg_verify_link_content', 'label' => '内容模板', 'type' => 'textarea', 'default' => ''],
['key' => 'email_reg_verify_link_html', 'label' => 'HTML 格式', 'type' => 'switch', 'default' => false],
]],
['key' => 'reg_verify_code', 'title' => '注册验证码', 'fields' => [
['key' => 'email_reg_verify_code_enabled', 'label' => '启用', 'type' => 'switch', 'default' => true],
['key' => 'email_reg_verify_code_subject', 'label' => '主题', 'type' => 'input', 'default' => ''],
['key' => 'email_reg_verify_code_content', 'label' => '内容模板', 'type' => 'textarea', 'default' => ''],
['key' => 'email_reg_verify_code_html', 'label' => 'HTML 格式', 'type' => 'switch', 'default' => false],
]],
['key' => 'reg_success', 'title' => '注册成功通知', 'fields' => [
['key' => 'email_reg_success_enabled', 'label' => '启用', 'type' => 'switch', 'default' => true],
['key' => 'email_reg_success_subject', 'label' => '主题', 'type' => 'input', 'default' => ''],
['key' => 'email_reg_success_content', 'label' => '内容模板', 'type' => 'textarea', 'default' => ''],
['key' => 'email_reg_success_html', 'label' => 'HTML 格式', 'type' => 'switch', 'default' => false],
]],
['key' => 'password_reset', 'title' => '密码重置', 'fields' => [
['key' => 'email_password_reset_enabled', 'label' => '启用', 'type' => 'switch', 'default' => true],
['key' => 'email_password_reset_subject', 'label' => '主题', 'type' => 'input', 'default' => ''],
['key' => 'email_password_reset_content', 'label' => '内容模板', 'type' => 'textarea', 'default' => ''],
['key' => 'email_password_reset_html', 'label' => 'HTML 格式', 'type' => 'switch', 'default' => false],
]],
['key' => 'change_code', 'title' => '邮箱变更验证码', 'fields' => [
['key' => 'email_change_code_enabled', 'label' => '启用', 'type' => 'switch', 'default' => true],
['key' => 'email_change_code_subject', 'label' => '主题', 'type' => 'input', 'default' => ''],
['key' => 'email_change_code_content', 'label' => '内容模板', 'type' => 'textarea', 'default' => ''],
['key' => 'email_change_code_html', 'label' => 'HTML 格式', 'type' => 'switch', 'default' => false],
]],
['key' => 'change_notice', 'title' => '邮箱变更通知', 'fields' => [
['key' => 'email_change_notice_enabled', 'label' => '启用', 'type' => 'switch', 'default' => true],
['key' => 'email_change_notice_subject', 'label' => '主题', 'type' => 'input', 'default' => ''],
['key' => 'email_change_notice_content', 'label' => '内容模板', 'type' => 'textarea', 'default' => ''],
['key' => 'email_change_notice_html', 'label' => 'HTML 格式', 'type' => 'switch', 'default' => false],
]],
],
],
'email' => \AKSRT\Settings\MailTemplates::build_schema(),
'custom-code' => [
'key' => 'custom-code',
'title' => '自定义代码',
+13 -3
View File
@@ -540,9 +540,15 @@ class SchemaProvider {
$data = $this->collect_defaults($schema);
foreach ($this->get_all_fields($schema) as $field) {
if (array_key_exists($field['key'], $stored)) {
$data[$field['key']] = $stored[$field['key']];
}
if (array_key_exists($field['key'], $stored)) {
$stored_value = $stored[$field['key']];
$is_mail_template = $option_key === 'aksrt_settings'
&& preg_match('/^email_.+_(subject|content)$/', (string) $field['key']);
if (!$is_mail_template || trim((string) $stored_value) !== '') {
$data[$field['key']] = $stored_value;
}
}
$stored_value = array_key_exists($field['key'], $stored) ? $stored[$field['key']] : ($data[$field['key']] ?? '');
if (!empty($field['secret'])) {
$data[$field['key']] = trim((string) $stored_value) !== '' ? '***' : '';
@@ -732,6 +738,10 @@ class SchemaProvider {
if (!is_array($field) || empty($field['key'])) {
continue;
}
// UI-only controls never become persisted settings keys.
if (!empty($field['ui_only'])) {
continue;
}
// Notice/help-only rows are UI chrome, not stored settings keys.
if (($field['type'] ?? '') === 'notice') {
continue;
-41
View File
@@ -87,13 +87,6 @@ class UserController extends ControllerBase {
'permission_callback' => [$this, 'check_permission'],
]);
// Mail templates (email content templates)
register_rest_route(self::API_NAMESPACE, '/settings/mail-templates', [
'methods' => ['GET', 'POST'],
'callback' => [$this, 'handle_mail_templates'],
'permission_callback' => [$this, 'check_permission'],
]);
register_rest_route(self::API_NAMESPACE, '/assets/settings', [
'methods' => ['GET', 'POST'],
'callback' => [$this, 'rest_handle_credit_settings'],
@@ -325,40 +318,6 @@ class UserController extends ControllerBase {
}
/**
* GET/POST /settings/mail-templates — 邮件内容模板
*/
public function handle_mail_templates(\WP_REST_Request $request): \WP_REST_Response {
$option_key = 'aksrt_mail_templates';
$fields = [
'welcome_subject', 'welcome_body',
'comment_notify_subject', 'comment_notify_body',
'comment_reply_subject', 'comment_reply_body',
'password_reset_subject', 'password_reset_body',
'email_verify_subject', 'email_verify_body',
];
if ($request->get_method() === 'GET') {
$stored = get_option($option_key, []);
if (!is_array($stored)) $stored = [];
$result = [];
foreach ($fields as $f) {
$result[$f] = sanitize_text_field((string) ($stored[$f] ?? ''));
}
return $this->success(['data' => $result]);
}
// POST
$params = $this->get_json_params($request);
$clean = [];
foreach ($fields as $f) {
$clean[$f] = wp_kses_post((string) ($params[$f] ?? ''));
}
update_option($option_key, $clean);
return $this->success(['message' => __('邮件模板已保存', 'aksrt')]);
}
public function rest_handle_credit_settings(\WP_REST_Request $request): \WP_REST_Response {
if ($request->get_method() === 'GET') {
$config = \AKSRT\Settings\CreditsRuntime::get_credit_settings();
@@ -191,17 +191,33 @@ trait UserControllerAuthPhoneOperations {
}
$code = (string) random_int(100000, 999999);
$this->auth_store_email_code($scene, $target, $code);
$subject = sprintf(__('[%s] 登录注册验证码', 'aksrt'), get_bloginfo('name'));
$message = sprintf(__('您的验证码是:%s,10 分钟内有效。', 'aksrt'), $code);
if (!wp_mail($target, $subject, $message)) {
$scene_event = [
'login' => 'login_code',
'register' => 'reg_verify_code',
'resetpassword' => 'password_reset',
][$scene] ?? '';
$user = $this->auth_find_user($target, $channel);
$display_name = $user instanceof \WP_User ? $user->display_name : $target;
$site_name = get_bloginfo('name');
$placeholders = [
'{username}' => $display_name,
'{site_name}' => $site_name,
'{code}' => $code,
];
$sent = $scene_event !== '' && class_exists('\\AKSRT\\Settings\\Settings')
? \AKSRT\Settings\Settings::send_event_email($scene_event, $target, '', '', $placeholders)
: false;
if (!$sent) {
delete_transient($this->auth_code_key($scene, $target));
if ($scene !== 'register') {
return $this->success(['message' => $generic, 'countdown' => 60]);
}
return $this->error(__('验证码发送失败,请稍后再试', 'aksrt'), 500);
}
$this->auth_store_email_code($scene, $target, $code);
return $this->success(['message' => $generic, 'countdown' => 60]);
}
public function auth_login(\WP_REST_Request $request): \WP_REST_Response {