refactor(autoload): migrate theme classes to Composer PSR-4
Move 288 types from global AKSRT_* + inc/classes manual requires into
namespace AKSRT\{Domain} under src/AKSRT/, wire composer.json psr-4,
and slim bootstrap to helpers/modules/hooks only. Split multi-class
widget/gateway files, update admin contract audit paths, and document
the layout in ADR/README.
This commit is contained in:
@@ -0,0 +1,392 @@
|
||||
<?php
|
||||
/**
|
||||
* User profile/password/email AJAX handlers
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
// ============================================================
|
||||
add_action('wp_ajax_aksrt_save_profile', function () {
|
||||
if (!isset($_POST['_profile_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_profile_nonce'])), 'aksrt_profile_save')) {
|
||||
wp_send_json_error(['message' => __('安全验证失败,请刷新页面重试', 'aksrt')]);
|
||||
}
|
||||
|
||||
$user_id = isset($_POST['user_id']) ? (int) $_POST['user_id'] : 0;
|
||||
$result = function_exists('aksrt_save_user_center_profile')
|
||||
? aksrt_save_user_center_profile($user_id, $_POST)
|
||||
: new WP_Error('aksrt_profile_unavailable', __('保存失败', 'aksrt'));
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
wp_send_json_error(['message' => $result->get_error_message()]);
|
||||
}
|
||||
|
||||
wp_send_json_success(['message' => __('保存成功!', 'aksrt')]);
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// AJAX: 上传打赏收款码
|
||||
// ============================================================
|
||||
add_action('wp_ajax_aksrt_upload_reward_qr', function () {
|
||||
if (!isset($_POST['_profile_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_profile_nonce'])), 'aksrt_profile_save')) {
|
||||
wp_send_json_error(['message' => __('安全验证失败,请刷新页面重试', 'aksrt')]);
|
||||
}
|
||||
$user_id = get_current_user_id();
|
||||
if ($user_id <= 0) {
|
||||
wp_send_json_error(['message' => __('请先登录', 'aksrt')]);
|
||||
}
|
||||
if (function_exists('aksrt_rewards_enabled') && !aksrt_rewards_enabled()) {
|
||||
wp_send_json_error(['message' => __('打赏功能未启用', 'aksrt')]);
|
||||
}
|
||||
$kind = isset($_POST['kind']) ? sanitize_key((string) $_POST['kind']) : '';
|
||||
if (!in_array($kind, ['weixin', 'alipay'], true)) {
|
||||
wp_send_json_error(['message' => __('无效类型', 'aksrt')]);
|
||||
}
|
||||
if (empty($_FILES['file']['name'])) {
|
||||
wp_send_json_error(['message' => __('请选择图片', 'aksrt')]);
|
||||
}
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/media.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
|
||||
$file = $_FILES['file'];
|
||||
$check = wp_check_filetype_and_ext($file['tmp_name'], $file['name']);
|
||||
$allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
||||
$mime = (string) ($check['type'] ?? $file['type'] ?? '');
|
||||
if ($mime === '' || !in_array($mime, $allowed, true)) {
|
||||
wp_send_json_error(['message' => __('仅支持 JPG/PNG/GIF/WebP 图片', 'aksrt')]);
|
||||
}
|
||||
if (!empty($file['size']) && (int) $file['size'] > 2 * 1024 * 1024) {
|
||||
wp_send_json_error(['message' => __('图片不能超过 2MB', 'aksrt')]);
|
||||
}
|
||||
|
||||
$attachment_id = media_handle_upload('file', 0);
|
||||
if (is_wp_error($attachment_id)) {
|
||||
wp_send_json_error(['message' => $attachment_id->get_error_message()]);
|
||||
}
|
||||
$meta = $kind === 'weixin' ? 'aksrt_rewards_weixin' : 'aksrt_rewards_alipay';
|
||||
update_user_meta($user_id, $meta, (int) $attachment_id);
|
||||
$url = wp_get_attachment_image_url((int) $attachment_id, 'full');
|
||||
wp_send_json_success([
|
||||
'message' => __('上传成功', 'aksrt'),
|
||||
'id' => (int) $attachment_id,
|
||||
'url' => is_string($url) ? $url : '',
|
||||
'kind' => $kind,
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
// ============================================================
|
||||
// AJAX: 发送邮箱验证码(修改密码/更改邮箱通用)
|
||||
// ============================================================
|
||||
|
||||
if (!function_exists('aksrt_get_email_code_key')) :
|
||||
function aksrt_get_email_code_key(int $user_id, string $scene): string {
|
||||
return 'aksrt_email_code_' . $scene . '_' . $user_id;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_email_code_rate_key')) :
|
||||
function aksrt_get_email_code_rate_key(int $user_id, string $scene, string $target = ''): string {
|
||||
$suffix = $target !== '' ? '_' . md5(strtolower($target)) : '';
|
||||
return 'aksrt_email_code_rate_' . $scene . '_' . $user_id . $suffix;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_store_email_code')) :
|
||||
function aksrt_store_email_code(int $user_id, string $scene, string $code, string $target = ''): void {
|
||||
set_transient(
|
||||
aksrt_get_email_code_key($user_id, $scene),
|
||||
[
|
||||
'hash' => wp_hash_password($code),
|
||||
'target' => $target,
|
||||
'issued_at' => time(),
|
||||
],
|
||||
5 * MINUTE_IN_SECONDS
|
||||
);
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_consume_email_code')) :
|
||||
function aksrt_consume_email_code(int $user_id, string $scene, string $code, string $target = ''): bool {
|
||||
$key = aksrt_get_email_code_key($user_id, $scene);
|
||||
$stored = get_transient($key);
|
||||
if (!is_array($stored) || empty($stored['hash']) || !wp_check_password($code, $stored['hash'])) {
|
||||
return false;
|
||||
}
|
||||
if ($target !== '' && strtolower((string) ($stored['target'] ?? '')) !== strtolower($target)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
delete_transient($key);
|
||||
return true;
|
||||
}
|
||||
|
||||
endif;
|
||||
|
||||
add_action('wp_ajax_aksrt_send_email_code', function () {
|
||||
if ( ! isset( $_POST['_settings_nonce'] ) || ! wp_verify_nonce( $_POST['_settings_nonce'], 'aksrt_account_settings' ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '安全验证失败,请刷新页面重试', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
if ( ! is_user_logged_in() ) {
|
||||
wp_send_json_error( array( 'message' => __( '请先登录', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
$scene = isset( $_POST['scene'] ) ? sanitize_key( (string) $_POST['scene'] ) : '';
|
||||
if ( ! in_array( $scene, array( 'change_password', 'change_email' ), true ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '无效的验证场景', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
if ( function_exists( 'aksrt_require_captcha' ) ) {
|
||||
$captcha_result = aksrt_require_captcha( $scene, wp_unslash( $_POST ) );
|
||||
if ( $captcha_result !== true ) {
|
||||
wp_send_json_error( array( 'message' => $captcha_result ) );
|
||||
}
|
||||
}
|
||||
|
||||
$current_user = wp_get_current_user();
|
||||
$target_email = '';
|
||||
$success_message = '';
|
||||
|
||||
if ( $scene === 'change_password' ) {
|
||||
$target_email = $current_user->user_email;
|
||||
if ( empty( $target_email ) || ! is_email( $target_email ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '当前账号未绑定有效邮箱', 'aksrt' ) ) );
|
||||
}
|
||||
$success_message = __( '验证码已发送到您的注册邮箱', 'aksrt' );
|
||||
} else {
|
||||
$new_email = isset( $_POST['new_email'] ) ? trim( wp_unslash( $_POST['new_email'] ) ) : '';
|
||||
$current_password = isset( $_POST['current_password'] ) ? trim( wp_unslash( $_POST['current_password'] ) ) : '';
|
||||
|
||||
if ( empty( $current_password ) || ! wp_check_password( $current_password, $current_user->user_pass, $current_user->ID ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '当前密码不正确', 'aksrt' ) ) );
|
||||
}
|
||||
if ( empty( $new_email ) || ! is_email( $new_email ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '请输入有效的新邮箱地址', 'aksrt' ) ) );
|
||||
}
|
||||
if ( strtolower( $new_email ) === strtolower( $current_user->user_email ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '新邮箱与当前邮箱相同', 'aksrt' ) ) );
|
||||
}
|
||||
if ( email_exists( $new_email ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '该邮箱已被其他账号使用', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
$target_email = $new_email;
|
||||
$success_message = __( '验证码已发送到新邮箱,请完成验证后再提交', 'aksrt' );
|
||||
}
|
||||
|
||||
// 频率限制:60秒内不能重复发送
|
||||
$rate_key = aksrt_get_email_code_rate_key( $current_user->ID, $scene, $target_email );
|
||||
if ( get_transient( $rate_key ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '操作过于频繁,请稍后再试', 'aksrt' ) ) );
|
||||
}
|
||||
set_transient( $rate_key, true, 60 );
|
||||
|
||||
// 生成验证码并同步发送,只有真正发信成功后才写入验证码缓存。
|
||||
$code = str_pad( (string) random_int( 0, 999999 ), 6, '0', STR_PAD_LEFT );
|
||||
|
||||
$site_name = get_bloginfo( 'name' );
|
||||
$default_subject = '[' . $site_name . '] ' . __( '邮箱验证码', 'aksrt' );
|
||||
$default_content = sprintf(
|
||||
__( "您好 %s,\n\n您正在进行敏感操作验证,验证码为:\n\n【%s】\n\n验证码有效期为 5 分钟。如非本人操作,请忽略此邮件。", 'aksrt' ),
|
||||
$current_user->display_name,
|
||||
$code
|
||||
);
|
||||
$sent = class_exists( '\AKSRT\Settings\Settings' )
|
||||
? \AKSRT\Settings\Settings::send_event_email(
|
||||
'change_code', $target_email, $default_subject, $default_content,
|
||||
[ '{username}' => $current_user->display_name, '{site_name}' => $site_name, '{code}' => $code ]
|
||||
)
|
||||
: wp_mail( $target_email, $default_subject, $default_content, [ 'Content-Type: text/plain; charset=UTF-8' ] );
|
||||
|
||||
if ( ! $sent ) {
|
||||
delete_transient( $rate_key );
|
||||
error_log( '[AKSRT] 验证码邮件发送失败 user_id=' . $current_user->ID . ' email=' . $target_email . ' scene=' . $scene );
|
||||
wp_send_json_error( array( 'message' => __( '验证码邮件发送失败,请稍后重试', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
aksrt_store_email_code( $current_user->ID, $scene, $code, $target_email );
|
||||
|
||||
wp_send_json_success( array( 'message' => $success_message ) );
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// AJAX: 修改密码
|
||||
// ============================================================
|
||||
add_action('wp_ajax_aksrt_change_password', function () {
|
||||
if ( ! isset( $_POST['_settings_nonce'] ) || ! wp_verify_nonce( $_POST['_settings_nonce'], 'aksrt_account_settings' ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '安全验证失败,请刷新页面重试', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
if ( ! $user_id ) {
|
||||
wp_send_json_error( array( 'message' => __( '请先登录', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
$old_password = isset( $_POST['old_password'] ) ? trim( wp_unslash( $_POST['old_password'] ) ) : '';
|
||||
$new_password = isset( $_POST['new_password'] ) ? trim( wp_unslash( $_POST['new_password'] ) ) : '';
|
||||
$new_password_confirm = isset( $_POST['new_password_confirm'] ) ? trim( wp_unslash( $_POST['new_password_confirm'] ) ) : '';
|
||||
$email_code = isset( $_POST['email_code'] ) ? sanitize_text_field( $_POST['email_code'] ) : '';
|
||||
|
||||
// 验证原密码
|
||||
$user = get_userdata( $user_id );
|
||||
if ( ! $user || ! wp_check_password( $old_password, $user->data->user_pass, $user_id ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '原密码不正确', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
// 验证新密码强度
|
||||
if ( mb_strlen( $new_password ) < 6 ) {
|
||||
wp_send_json_error( array( 'message' => __( '新密码长度至少6位', 'aksrt' ) ) );
|
||||
}
|
||||
if ( mb_strlen( $new_password ) > 128 ) {
|
||||
wp_send_json_error( array( 'message' => __( '新密码过长', 'aksrt' ) ) );
|
||||
}
|
||||
if ( $new_password !== $new_password_confirm ) {
|
||||
wp_send_json_error( array( 'message' => __( '两次输入的新密码不一致', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
// 人机验证
|
||||
if ( function_exists( 'aksrt_require_captcha' ) ) {
|
||||
$captcha_result = aksrt_require_captcha( 'change_password', wp_unslash( $_POST ) );
|
||||
if ( $captcha_result !== true ) {
|
||||
wp_send_json_error( array( 'message' => $captcha_result ) );
|
||||
}
|
||||
}
|
||||
|
||||
// 验证邮箱验证码
|
||||
if ( ! aksrt_consume_email_code( $user_id, 'change_password', $email_code, $user->user_email ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '邮箱验证码错误或已过期', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
// 设置新密码
|
||||
wp_set_password( $new_password, $user_id );
|
||||
|
||||
if ( class_exists( 'WP_Session_Tokens' ) ) {
|
||||
WP_Session_Tokens::get_instance( $user_id )->destroy_all();
|
||||
}
|
||||
|
||||
// 清除登录态
|
||||
wp_clear_auth_cookie();
|
||||
|
||||
wp_send_json_success( array(
|
||||
'message' => __( '密码修改成功,即将跳转到登录页…', 'aksrt' ),
|
||||
'redirect_to' => aksrt_get_login_url(),
|
||||
));
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// AJAX: 更改邮箱
|
||||
// ============================================================
|
||||
add_action('wp_ajax_aksrt_change_email', function () {
|
||||
if ( ! isset( $_POST['_settings_nonce'] ) || ! wp_verify_nonce( $_POST['_settings_nonce'], 'aksrt_account_settings' ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '安全验证失败,请刷新页面重试', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
if ( ! $user_id ) {
|
||||
wp_send_json_error( array( 'message' => __( '请先登录', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
$current_password = isset( $_POST['current_password'] ) ? trim( wp_unslash( $_POST['current_password'] ) ) : '';
|
||||
$new_email = isset( $_POST['new_email'] ) ? trim( wp_unslash( $_POST['new_email'] ) ) : '';
|
||||
$email_code = isset( $_POST['email_code'] ) ? sanitize_text_field( $_POST['email_code'] ) : '';
|
||||
|
||||
$current_user = wp_get_current_user();
|
||||
if ( empty( $current_password ) || ! wp_check_password( $current_password, $current_user->user_pass, $current_user->ID ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '当前密码不正确', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
// 验证新邮箱格式
|
||||
if ( empty( $new_email ) || ! is_email( $new_email ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '请输入有效的邮箱地址', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
if ( strtolower( $new_email ) === strtolower( $current_user->user_email ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '新邮箱与当前邮箱相同', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
// 检查邮箱是否已被使用
|
||||
if ( email_exists( $new_email ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '该邮箱已被其他账号使用', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
// 人机验证
|
||||
if ( function_exists( 'aksrt_require_captcha' ) ) {
|
||||
$captcha_result = aksrt_require_captcha( 'change_email', wp_unslash( $_POST ) );
|
||||
if ( $captcha_result !== true ) {
|
||||
wp_send_json_error( array( 'message' => $captcha_result ) );
|
||||
}
|
||||
}
|
||||
|
||||
// 验证邮箱验证码
|
||||
if ( ! aksrt_consume_email_code( $user_id, 'change_email', $email_code, $new_email ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '邮箱验证码错误或已过期', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
// 更新邮箱
|
||||
$old_email = $current_user->user_email;
|
||||
$update_result = wp_update_user( [
|
||||
'ID' => $user_id,
|
||||
'user_email' => $new_email,
|
||||
] );
|
||||
|
||||
if ( is_wp_error( $update_result ) ) {
|
||||
wp_send_json_error( array( 'message' => $update_result->get_error_message() ?: __( '邮箱更新失败,请稍后重试', 'aksrt' ) ) );
|
||||
}
|
||||
|
||||
if ( is_email( $old_email ) ) {
|
||||
$site_name = get_bloginfo( 'name' );
|
||||
$default_subject = '[' . $site_name . '] ' . __( '账号邮箱已变更', 'aksrt' );
|
||||
$default_content = sprintf(
|
||||
__( "您好 %s,\n\n您的账号邮箱已成功修改为:%s\n\n如果这不是您的操作,请立即联系站点管理员。", 'aksrt' ),
|
||||
$current_user->display_name,
|
||||
$new_email
|
||||
);
|
||||
if ( class_exists( '\AKSRT\Settings\Settings' ) ) {
|
||||
\AKSRT\Settings\Settings::send_event_email(
|
||||
'change_notice', $old_email, $default_subject, $default_content,
|
||||
[ '{username}' => $current_user->display_name, '{site_name}' => $site_name, '{new_email}' => $new_email ]
|
||||
);
|
||||
} else {
|
||||
wp_mail( $old_email, $default_subject, $default_content, [ 'Content-Type: text/plain; charset=UTF-8' ] );
|
||||
}
|
||||
}
|
||||
|
||||
// ====== 邮箱变更后重置验证状态(阶段 5)======
|
||||
// 1. 写入 14 天回滚窗口 meta(管理员可在此期内还原旧邮箱)
|
||||
// 2. 把 aksrt_email_verified 重置为 0
|
||||
// 3. 若功能启用 → 立即给新邮箱发送验证邮件
|
||||
update_user_meta( $user_id, 'aksrt_email_previous', $old_email );
|
||||
update_user_meta( $user_id, 'aksrt_email_changed_at', time() );
|
||||
|
||||
$verify_url = '';
|
||||
$verify_message = '';
|
||||
if ( class_exists( '\AKSRT\Settings\Settings' ) && class_exists( '\AKSRT\Auth\Service' )
|
||||
&& \AKSRT\Settings\Settings::registration_requires_email_verification() ) {
|
||||
update_user_meta( $user_id, 'aksrt_email_verified', 0 );
|
||||
// 用户对自身的 edit_user 权限映射到 'read',因此 admin_send_verification 会通过权限校验。
|
||||
$verify_result = \AKSRT\Auth\Service::admin_send_verification( $user_id, $user_id );
|
||||
if ( ! empty( $verify_result['success'] ) ) {
|
||||
$verify_url = function_exists('aksrt_get_verify_email_url') ? aksrt_get_verify_email_url( $user_id ) : '';
|
||||
$verify_message = __( '请前往新邮箱完成验证,否则下次登录将被拦截。', 'aksrt' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( class_exists( 'WP_Session_Tokens' ) ) {
|
||||
WP_Session_Tokens::get_instance( $user_id )->destroy_all();
|
||||
}
|
||||
|
||||
// 清除登录态
|
||||
wp_clear_auth_cookie();
|
||||
|
||||
wp_send_json_success( array(
|
||||
'message' => $verify_message !== ''
|
||||
? __( '邮箱修改成功,请前往新邮箱完成验证后重新登录…', 'aksrt' )
|
||||
: __( '邮箱修改成功,即将跳转到登录页…', 'aksrt' ),
|
||||
'redirect_to' => $verify_url !== '' ? $verify_url : aksrt_get_login_url(),
|
||||
'verify_url' => $verify_url,
|
||||
));
|
||||
});
|
||||
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/**
|
||||
* User rewrite/routing/bootstrap flush + author redirects
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
// ============================================================
|
||||
// 三、URL 路由与模板加载
|
||||
// ============================================================
|
||||
|
||||
// --- 3a. /user/{昵称} 自定义重写 ---
|
||||
add_filter('query_vars', function ($vars) {
|
||||
$vars[] = 'aksrt_user_center';
|
||||
$vars[] = 'user_nicename';
|
||||
return $vars;
|
||||
});
|
||||
|
||||
add_action('template_redirect', function () {
|
||||
if (is_admin() || wp_doing_ajax() || is_feed() || is_embed() || is_preview()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$resolved_path = aksrt_get_current_special_template_path();
|
||||
if ($resolved_path === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
status_header(200);
|
||||
load_template($resolved_path, true);
|
||||
exit;
|
||||
}, 100);
|
||||
|
||||
add_action('init', function () {
|
||||
add_rewrite_tag('%aksrt_user_center%', '([^&]+)');
|
||||
add_rewrite_tag('%user_nicename%', '([^/]+)');
|
||||
add_rewrite_rule('^profile/?$', 'index.php?aksrt_user_center=1', 'top');
|
||||
add_rewrite_rule('^user/([^/]+)/?$', 'index.php?user_nicename=$matches[1]', 'top');
|
||||
});
|
||||
|
||||
// --- 3b. 统一模板拦截器(核心)---
|
||||
// 拦截所有使用主题特殊模板的页面请求,确保正确加载
|
||||
add_filter('template_include', function ($template) {
|
||||
$resolved_path = aksrt_get_current_special_template_path();
|
||||
if ($resolved_path !== '') {
|
||||
return $resolved_path;
|
||||
}
|
||||
|
||||
return $template;
|
||||
|
||||
global $_aksrt_special_templates;
|
||||
|
||||
// A) /user/{昵称} 路由 → 加载公开主页模板
|
||||
$nicename = get_query_var('user_nicename');
|
||||
if (!empty($nicename)) {
|
||||
$user = get_user_by('slug', $nicename);
|
||||
if (!$user) return $template; // 不存在的用户 → 默认 404
|
||||
|
||||
$tpl = aksrt_locate_template_file('templates/pages/page-user-home.php');
|
||||
if (!$tpl) {
|
||||
// 兜底:如果新模板不存在,回退到旧 profile 模板
|
||||
$tpl = aksrt_locate_template_file($_aksrt_special_templates['profile']['file']);
|
||||
}
|
||||
if (!$tpl) return $template;
|
||||
|
||||
global $aksrt_profile_user;
|
||||
$aksrt_profile_user = $user;
|
||||
return $tpl;
|
||||
}
|
||||
|
||||
// B) 普通页面 → 检测是否使用了我们的特殊模板,确保加载正确的模板文件
|
||||
// (防止 WP 在某些情况下未能正确解析自定义页面模板)
|
||||
if (is_page()) {
|
||||
$page_id = get_queried_object_id();
|
||||
if ($page_id) {
|
||||
$page_template = get_post_meta($page_id, '_wp_page_template', true);
|
||||
if ($page_template && strpos($page_template, 'templates/pages/') === 0) {
|
||||
$tpl = aksrt_locate_template_file($page_template);
|
||||
if ($tpl) return $tpl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $template;
|
||||
}, 99);
|
||||
|
||||
add_filter('template_include', function ($template) {
|
||||
$resolved_path = aksrt_get_current_special_template_path();
|
||||
if ($resolved_path !== '') {
|
||||
return $resolved_path;
|
||||
}
|
||||
|
||||
if (get_query_var('aksrt_user_center')) {
|
||||
$profile_template = aksrt_locate_template_file('templates/pages/page-profile.php');
|
||||
if ($profile_template) {
|
||||
return $profile_template;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_page()) {
|
||||
$page_id = get_queried_object_id();
|
||||
if ($page_id > 0) {
|
||||
$page_template = get_post_meta($page_id, '_wp_page_template', true);
|
||||
$resolved_template = aksrt_resolve_page_template_file(
|
||||
is_string($page_template) ? $page_template : '',
|
||||
(string) get_post_field('post_name', $page_id)
|
||||
);
|
||||
|
||||
if ($resolved_template !== '') {
|
||||
$resolved_path = aksrt_locate_template_file($resolved_template);
|
||||
if ($resolved_path) {
|
||||
return $resolved_path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $template;
|
||||
}, 100);
|
||||
|
||||
// ============================================================
|
||||
// 四、自动维护 + flush
|
||||
// ============================================================
|
||||
add_action('init', function () {
|
||||
global $_aksrt_special_templates;
|
||||
|
||||
// 后台/AJAX:检查并创建缺失页面
|
||||
$pages_bootstrapped = get_option('aksrt_template_pages_bootstrapped');
|
||||
$requested_template_key = (!is_admin() && !wp_doing_ajax()) ? aksrt_get_requested_template_key() : '';
|
||||
if (is_admin() || wp_doing_ajax() || $pages_bootstrapped !== AKSRT_VERSION) {
|
||||
foreach ($_aksrt_special_templates as $key => $cfg) {
|
||||
if ($key === 'profile') {
|
||||
continue;
|
||||
}
|
||||
aksrt_ensure_template_page($key);
|
||||
}
|
||||
|
||||
if ($pages_bootstrapped !== AKSRT_VERSION) {
|
||||
update_option('aksrt_template_pages_bootstrapped', AKSRT_VERSION);
|
||||
}
|
||||
} elseif ($requested_template_key !== '' && $requested_template_key !== 'profile') {
|
||||
aksrt_ensure_template_page($requested_template_key);
|
||||
}
|
||||
|
||||
// 统一 flush 检查
|
||||
$rewrite_version = AKSRT_VERSION . ':sign-profile-routing-v1';
|
||||
$flushed = get_option('aksrt_user_rules_flushed');
|
||||
if ($flushed !== $rewrite_version) {
|
||||
flush_rewrite_rules(false);
|
||||
update_option('aksrt_user_rules_flushed', $rewrite_version);
|
||||
}
|
||||
});
|
||||
|
||||
// 页面变更时清缓存
|
||||
add_action('save_post', function ($pid) { if (get_post_type($pid) === 'page') aksrt_clear_template_page_cache(); });
|
||||
add_action('delete_post', function ($pid) { if (get_post_type($pid) === 'page') aksrt_clear_template_page_cache(); });
|
||||
|
||||
// ============================================================
|
||||
// 六、作者链接改写
|
||||
// ============================================================
|
||||
add_filter('author_link', function ($link, $author_id) {
|
||||
$user = get_userdata($author_id);
|
||||
$slug = $user ? $user->user_nicename : 'user-' . $author_id;
|
||||
return home_url('/user/' . trailingslashit($slug));
|
||||
}, 10, 2);
|
||||
|
||||
add_action('template_redirect', function () {
|
||||
if (!is_author()) return;
|
||||
$author_id = get_queried_object_id();
|
||||
if ($author_id) {
|
||||
$user = get_userdata($author_id);
|
||||
$slug = $user ? $user->user_nicename : 'user-' . $author_id;
|
||||
wp_safe_redirect(home_url('/user/' . trailingslashit($slug)), 301);
|
||||
exit;
|
||||
}
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// AJAX: 保存用户个人资料(显示名称、简介、联系方式)
|
||||
@@ -0,0 +1,492 @@
|
||||
<?php
|
||||
/**
|
||||
* User template registry + template utils
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
// ============================================================
|
||||
// 一、模板注册表 — 所有特殊页面的"身份证"
|
||||
// 修改此处即可增删模板页面,无需改动其他逻辑
|
||||
// ============================================================
|
||||
$_aksrt_special_templates = [
|
||||
'login' => [
|
||||
'file' => 'templates/pages/page-login.php',
|
||||
'slug' => 'login',
|
||||
'title' => '登录',
|
||||
'fallback' => '/login/',
|
||||
],
|
||||
'register' => [
|
||||
'file' => 'templates/pages/page-register.php',
|
||||
'slug' => 'register',
|
||||
'title' => '注册',
|
||||
'fallback' => '/register/',
|
||||
],
|
||||
'bind' => [
|
||||
'file' => 'templates/pages/page-bind-account.php',
|
||||
'slug' => 'bind-account',
|
||||
'title' => '绑定账号',
|
||||
'fallback' => '/bind-account/',
|
||||
],
|
||||
'reset-password' => [
|
||||
'file' => 'templates/pages/page-reset-password.php',
|
||||
'slug' => 'reset-password',
|
||||
'title' => '重置密码',
|
||||
'fallback' => '/reset-password/',
|
||||
],
|
||||
'verify-email' => [
|
||||
'file' => 'templates/pages/page-verify-email.php',
|
||||
'slug' => 'verify-email',
|
||||
'title' => '邮箱验证',
|
||||
'fallback' => '/verify-email/',
|
||||
],
|
||||
'categories' => [
|
||||
'file' => 'templates/pages/page-categories.php',
|
||||
'slug' => 'categories',
|
||||
'title' => '分类目录',
|
||||
'fallback' => '/categories/',
|
||||
],
|
||||
'friends' => [
|
||||
'file' => 'templates/pages/page-friends.php',
|
||||
'slug' => 'friends',
|
||||
'title' => '友情链接',
|
||||
'fallback' => '/friends/',
|
||||
],
|
||||
'profile' => [
|
||||
'file' => 'templates/pages/page-profile.php',
|
||||
'slug' => 'profile',
|
||||
'title' => '个人中心',
|
||||
'fallback' => '/',
|
||||
],
|
||||
];
|
||||
|
||||
// Zibll-style v2 routing keeps only true fixed template pages in the registry.
|
||||
$_aksrt_special_templates = [
|
||||
'sign' => [
|
||||
'file' => 'templates/pages/page-sign.php',
|
||||
'slug' => 'sign',
|
||||
'title' => '登录/注册',
|
||||
'fallback' => '/sign/',
|
||||
],
|
||||
'bind' => [
|
||||
'file' => 'templates/pages/page-bind-account.php',
|
||||
'slug' => 'bind-account',
|
||||
'title' => '绑定账号',
|
||||
'fallback' => '/bind-account/',
|
||||
],
|
||||
'reset-password' => [
|
||||
'file' => 'templates/pages/page-reset-password.php',
|
||||
'slug' => 'reset-password',
|
||||
'title' => '重置密码',
|
||||
'fallback' => '/reset-password/',
|
||||
],
|
||||
'verify-email' => [
|
||||
'file' => 'templates/pages/page-verify-email.php',
|
||||
'slug' => 'verify-email',
|
||||
'title' => '邮箱验证',
|
||||
'fallback' => '/verify-email/',
|
||||
],
|
||||
'categories' => [
|
||||
'file' => 'templates/pages/page-categories.php',
|
||||
'slug' => 'categories',
|
||||
'title' => '分类目录',
|
||||
'fallback' => '/categories/',
|
||||
],
|
||||
'friends' => [
|
||||
'file' => 'templates/pages/page-friends.php',
|
||||
'slug' => 'friends',
|
||||
'title' => '友情链接',
|
||||
'fallback' => '/friends/',
|
||||
],
|
||||
'profile' => [
|
||||
'file' => 'templates/pages/page-profile.php',
|
||||
'slug' => 'profile',
|
||||
'title' => '个人中心',
|
||||
'fallback' => '/profile/',
|
||||
],
|
||||
];
|
||||
|
||||
/** @var array 缓存 key=模板文件路径 => value=WP_Post|null */
|
||||
$_aksrt_template_page_cache = [];
|
||||
|
||||
|
||||
// ============================================================
|
||||
// 二、核心工具函数
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* 查找使用指定模板文件的页面(按模板匹配,自适应任意 slug)
|
||||
*
|
||||
* @param string $template_file 相对于主题的模板路径
|
||||
* @return WP_Post|null
|
||||
*/
|
||||
function aksrt_find_template_page(string $template_file) {
|
||||
global $_aksrt_template_page_cache;
|
||||
if (isset($_aksrt_template_page_cache[$template_file])) {
|
||||
return $_aksrt_template_page_cache[$template_file];
|
||||
}
|
||||
|
||||
$page = null;
|
||||
$pages = get_pages([
|
||||
'meta_key' => '_wp_page_template',
|
||||
'meta_value' => $template_file,
|
||||
'number' => 1,
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
if (!empty($pages)) {
|
||||
$page = $pages[0];
|
||||
}
|
||||
|
||||
$_aksrt_template_page_cache[$template_file] = $page;
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取使用指定模板的页面 URL
|
||||
*
|
||||
* @param string $key 注册表 key(当前仅 profile 使用)
|
||||
* @return string 页面 URL 或回退地址
|
||||
*/
|
||||
function aksrt_get_template_url(string $key): string {
|
||||
global $_aksrt_special_templates;
|
||||
if (!isset($_aksrt_special_templates[$key])) {
|
||||
return home_url('/');
|
||||
}
|
||||
|
||||
$cfg = $_aksrt_special_templates[$key];
|
||||
$page = aksrt_find_template_page($cfg['file']);
|
||||
|
||||
if (!$page) {
|
||||
aksrt_ensure_template_page($key);
|
||||
$page = aksrt_find_template_page($cfg['file']);
|
||||
}
|
||||
|
||||
if ($page) {
|
||||
return get_permalink($page->ID);
|
||||
}
|
||||
|
||||
return home_url($cfg['fallback']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 定位模板文件的绝对路径
|
||||
*
|
||||
* @param string $template_file 相对于主题的路径
|
||||
* @return string|false 文件绝对路径或 false
|
||||
*/
|
||||
function aksrt_locate_template_file(string $template_file) {
|
||||
$path = locate_template([$template_file]);
|
||||
if ($path) return $path;
|
||||
|
||||
$full = AKSRT_DIR . '/' . $template_file;
|
||||
return file_exists($full) ? $full : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a public-facing page template file from stored meta or page slug.
|
||||
*/
|
||||
function aksrt_resolve_page_template_file(string $template_file = '', string $post_slug = ''): string {
|
||||
$template_file = ltrim($template_file, '/\\');
|
||||
$post_slug = sanitize_title($post_slug);
|
||||
|
||||
$legacy_auth_templates = [
|
||||
'templates/pages/page-login.php' => 'login',
|
||||
'templates/pages/page-register.php' => 'register',
|
||||
'templates/pages/page-bind-account.php' => 'bind',
|
||||
'templates/pages/page-reset-password.php' => 'reset-password',
|
||||
'templates/pages/page-verify-email.php' => 'verify-email',
|
||||
];
|
||||
|
||||
if ($template_file !== '') {
|
||||
if ($template_file === 'templates/pages/page-sign.php') {
|
||||
return aksrt_get_auth_template_file(aksrt_get_auth_tab(), true);
|
||||
}
|
||||
|
||||
if (!empty($legacy_auth_templates[$template_file])) {
|
||||
return aksrt_get_auth_template_file((string) $legacy_auth_templates[$template_file], true);
|
||||
}
|
||||
|
||||
if (strpos($template_file, 'templates/pages/') === 0 && aksrt_locate_template_file($template_file)) {
|
||||
return $template_file;
|
||||
}
|
||||
}
|
||||
|
||||
if ($post_slug !== '') {
|
||||
$auth_slug_map = [
|
||||
'sign' => aksrt_get_auth_tab(),
|
||||
'login' => 'login',
|
||||
'register' => 'register',
|
||||
'bind-account' => 'bind',
|
||||
'reset-password' => 'reset-password',
|
||||
'verify-email' => 'verify-email',
|
||||
];
|
||||
|
||||
if (!empty($auth_slug_map[$post_slug])) {
|
||||
return aksrt_get_auth_template_file((string) $auth_slug_map[$post_slug], true);
|
||||
}
|
||||
|
||||
$slug_map = [
|
||||
'categories' => 'templates/pages/page-categories.php',
|
||||
'friends' => 'templates/pages/page-friends.php',
|
||||
'profile' => 'templates/pages/page-profile.php',
|
||||
];
|
||||
|
||||
if (!empty($slug_map[$post_slug]) && aksrt_locate_template_file($slug_map[$post_slug])) {
|
||||
return $slug_map[$post_slug];
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize auth view keys used by the unified sign page.
|
||||
*/
|
||||
function aksrt_normalize_auth_tab(string $tab): string {
|
||||
$tab = sanitize_key($tab);
|
||||
|
||||
switch ($tab) {
|
||||
case 'signin':
|
||||
case 'login':
|
||||
return 'login';
|
||||
case 'signup':
|
||||
case 'register':
|
||||
return 'register';
|
||||
case 'bind':
|
||||
case 'bind-account':
|
||||
return 'bind';
|
||||
case 'reset':
|
||||
case 'lostpassword':
|
||||
case 'reset-password':
|
||||
return 'reset-password';
|
||||
case 'verify':
|
||||
case 'verify-email':
|
||||
return 'verify-email';
|
||||
default:
|
||||
return 'login';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether an auth tab should be rendered by the unified sign page.
|
||||
*/
|
||||
function aksrt_auth_tab_uses_unified_sign_page(string $tab): bool {
|
||||
return in_array(
|
||||
aksrt_normalize_auth_tab($tab),
|
||||
['login', 'register'],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the auth template file, preferring the unified sign page when present.
|
||||
*/
|
||||
function aksrt_get_auth_template_file(string $tab = 'login', bool $prefer_sign_page = true): string {
|
||||
$normalized_tab = aksrt_normalize_auth_tab($tab);
|
||||
$sign_template = 'templates/pages/page-sign.php';
|
||||
|
||||
if (
|
||||
$prefer_sign_page
|
||||
&& aksrt_auth_tab_uses_unified_sign_page($normalized_tab)
|
||||
&& aksrt_locate_template_file($sign_template)
|
||||
) {
|
||||
return $sign_template;
|
||||
}
|
||||
|
||||
switch ($normalized_tab) {
|
||||
case 'register':
|
||||
return 'templates/pages/page-register.php';
|
||||
case 'bind':
|
||||
return 'templates/pages/page-bind-account.php';
|
||||
case 'reset-password':
|
||||
return 'templates/pages/page-reset-password.php';
|
||||
case 'verify-email':
|
||||
return 'templates/pages/page-verify-email.php';
|
||||
default:
|
||||
return 'templates/pages/page-login.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the active auth view for sign routes and the sign page template.
|
||||
*/
|
||||
function aksrt_get_auth_tab(): string {
|
||||
$query_tab = get_query_var('aksrt_auth_tab');
|
||||
if (is_string($query_tab) && $query_tab !== '') {
|
||||
return aksrt_normalize_auth_tab($query_tab);
|
||||
}
|
||||
|
||||
if (!empty($_GET['tab'])) {
|
||||
return aksrt_normalize_auth_tab((string) wp_unslash($_GET['tab']));
|
||||
}
|
||||
|
||||
$post = get_queried_object();
|
||||
if ($post instanceof WP_Post) {
|
||||
return aksrt_normalize_auth_tab((string) $post->post_name);
|
||||
}
|
||||
|
||||
return 'login';
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除模板页面缓存
|
||||
*/
|
||||
function aksrt_clear_template_page_cache(): void {
|
||||
global $_aksrt_template_page_cache;
|
||||
$_aksrt_template_page_cache = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the public user-home template context and return its template path.
|
||||
*/
|
||||
function aksrt_get_user_home_template_path(): string {
|
||||
global $_aksrt_special_templates, $aksrt_profile_user;
|
||||
|
||||
$nicename = (string) get_query_var('user_nicename');
|
||||
if ($nicename === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$user = get_user_by('slug', $nicename);
|
||||
if (!$user instanceof WP_User) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$template_path = aksrt_locate_template_file('templates/pages/page-user-home.php');
|
||||
|
||||
if (!$template_path) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$aksrt_profile_user = $user;
|
||||
return $template_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the active special-page template path for the current request.
|
||||
*/
|
||||
function aksrt_get_current_special_template_path(): string {
|
||||
if (get_query_var('user_nicename')) {
|
||||
return aksrt_get_user_home_template_path();
|
||||
}
|
||||
|
||||
if (get_query_var('aksrt_user_center')) {
|
||||
$profile_template = aksrt_locate_template_file('templates/pages/page-profile.php');
|
||||
return $profile_template ?: '';
|
||||
}
|
||||
|
||||
if (get_query_var('aksrt_sign')) {
|
||||
$auth_template = aksrt_get_auth_template_file((string) get_query_var('aksrt_auth_tab'), true);
|
||||
$auth_template_path = aksrt_locate_template_file($auth_template);
|
||||
return $auth_template_path ?: '';
|
||||
}
|
||||
|
||||
if (is_page()) {
|
||||
$page_id = get_queried_object_id();
|
||||
if ($page_id > 0) {
|
||||
$page_template = get_post_meta($page_id, '_wp_page_template', true);
|
||||
$resolved_template = aksrt_resolve_page_template_file(
|
||||
is_string($page_template) ? $page_template : '',
|
||||
(string) get_post_field('post_name', $page_id)
|
||||
);
|
||||
|
||||
if ($resolved_template !== '') {
|
||||
$resolved_path = aksrt_locate_template_file($resolved_template);
|
||||
if ($resolved_path) {
|
||||
return $resolved_path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前请求路径识别系统模板页 key。
|
||||
*
|
||||
* 用于前台直接访问固定 slug 时的自动补页。
|
||||
*/
|
||||
function aksrt_get_requested_template_key(): string {
|
||||
global $_aksrt_special_templates;
|
||||
|
||||
$request_uri = isset($_SERVER['REQUEST_URI']) ? (string) $_SERVER['REQUEST_URI'] : '';
|
||||
if ($request_uri === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$request_path = wp_parse_url($request_uri, PHP_URL_PATH);
|
||||
if (!is_string($request_path) || $request_path === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$home_path = (string) wp_parse_url(home_url('/'), PHP_URL_PATH);
|
||||
if ($home_path !== '' && str_starts_with($request_path, $home_path)) {
|
||||
$request_path = (string) substr($request_path, strlen($home_path));
|
||||
}
|
||||
|
||||
$request_slug = trim($request_path, '/');
|
||||
if ($request_slug === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
foreach ($_aksrt_special_templates as $key => $cfg) {
|
||||
$slug = isset($cfg['slug']) ? sanitize_title((string) $cfg['slug']) : '';
|
||||
if ($slug !== '' && $slug === $request_slug) {
|
||||
return (string) $key;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保使用指定模板的页面存在,缺失则自动创建
|
||||
*
|
||||
* @param string $key 注册表 key
|
||||
*/
|
||||
function aksrt_ensure_template_page(string $key): void {
|
||||
global $_aksrt_special_templates;
|
||||
if (!isset($_aksrt_special_templates[$key])) return;
|
||||
|
||||
$cfg = $_aksrt_special_templates[$key];
|
||||
$desired_slug = sanitize_title($cfg['slug'] ?? $key);
|
||||
|
||||
// 已有页面使用此模板?
|
||||
if (aksrt_find_template_page($cfg['file'])) return;
|
||||
|
||||
if ($desired_slug !== '') {
|
||||
$existing_page = get_page_by_path($desired_slug, OBJECT, 'page');
|
||||
if ($existing_page instanceof WP_Post) {
|
||||
if ($existing_page->post_status !== 'publish') {
|
||||
wp_update_post([
|
||||
'ID' => $existing_page->ID,
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
}
|
||||
|
||||
update_post_meta($existing_page->ID, '_wp_page_template', $cfg['file']);
|
||||
aksrt_clear_template_page_cache();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 自动创建
|
||||
$page_id = wp_insert_post([
|
||||
'post_title' => $cfg['title'],
|
||||
'post_content' => '',
|
||||
'post_status' => 'publish',
|
||||
'post_type' => 'page',
|
||||
'post_name' => $desired_slug !== '' ? $desired_slug : $key,
|
||||
'comment_status' => 'closed',
|
||||
'ping_status' => 'closed',
|
||||
]);
|
||||
|
||||
if (!is_wp_error($page_id) && $page_id > 0) {
|
||||
update_post_meta($page_id, '_wp_page_template', $cfg['file']);
|
||||
aksrt_clear_template_page_cache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
/**
|
||||
* User public URL/page API
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
// ============================================================
|
||||
// 五、公开 API 函数(兼容旧代码调用)
|
||||
// ============================================================
|
||||
|
||||
if (!function_exists('aksrt_get_user_center_url')) :
|
||||
/**
|
||||
* 获取本人中心 URL(私有空间入口)
|
||||
*
|
||||
* @param string $tab 可选 tab 参数
|
||||
* @return string
|
||||
*/
|
||||
function aksrt_get_user_center_url(string $tab = ''): string {
|
||||
if (get_option('permalink_structure')) {
|
||||
$url = home_url('/profile/');
|
||||
} else {
|
||||
$url = add_query_arg('aksrt_user_center', '1', home_url('/'));
|
||||
}
|
||||
|
||||
if ($tab !== '') {
|
||||
$url = add_query_arg('tab', $tab, $url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_orders_page_url')) :
|
||||
/**
|
||||
* 订单中心页面 URL(模板 templates/pages/page-orders.php)。
|
||||
* 未指派页面时返回空串,调用方应隐藏入口。
|
||||
*/
|
||||
function aksrt_get_orders_page_url(): string {
|
||||
return function_exists('aksrt_get_page_url_by_template')
|
||||
? aksrt_get_page_url_by_template('templates/pages/page-orders.php')
|
||||
: '';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_cart_page_url')) :
|
||||
/**
|
||||
* 购物车页面 URL(模板 templates/pages/page-cart.php)。
|
||||
*/
|
||||
function aksrt_get_cart_page_url(): string {
|
||||
return function_exists('aksrt_get_page_url_by_template')
|
||||
? aksrt_get_page_url_by_template('templates/pages/page-cart.php')
|
||||
: '';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_revenue_page_url')) :
|
||||
/**
|
||||
* 收益中心页面 URL(模板 templates/pages/page-revenue.php)。
|
||||
*/
|
||||
function aksrt_get_revenue_page_url(): string {
|
||||
return function_exists('aksrt_get_page_url_by_template')
|
||||
? aksrt_get_page_url_by_template('templates/pages/page-revenue.php')
|
||||
: '';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_messages_page_url')) :
|
||||
/**
|
||||
* 消息中心页面 URL(模板 templates/pages/page-messages.php)。
|
||||
*/
|
||||
function aksrt_get_messages_page_url(): string {
|
||||
return function_exists('aksrt_get_page_url_by_template')
|
||||
? aksrt_get_page_url_by_template('templates/pages/page-messages.php')
|
||||
: '';
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_user_home_url')) :
|
||||
/**
|
||||
* 获取公开用户主页 URL(/user/{nicename}/)
|
||||
*
|
||||
* @param WP_User|int|string|null $user 用户对象、ID、nicename 或 null(当前用户)
|
||||
* @return string
|
||||
*/
|
||||
function aksrt_get_user_home_url($user = null): string {
|
||||
$slug = '';
|
||||
if ($user instanceof WP_User) {
|
||||
$slug = $user->user_nicename;
|
||||
} elseif (is_int($user) && $user > 0) {
|
||||
$u = get_userdata($user);
|
||||
$slug = $u ? $u->user_nicename : '';
|
||||
} elseif (is_string($user) && $user) {
|
||||
$slug = $user;
|
||||
} else {
|
||||
$current = wp_get_current_user();
|
||||
$slug = $current->ID ? $current->user_nicename : '';
|
||||
}
|
||||
if (!$slug) return home_url('/');
|
||||
return home_url('/user/' . trailingslashit($slug));
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_is_user_center_page')) :
|
||||
/**
|
||||
* 判断当前是否为本人中心页面
|
||||
*/
|
||||
function aksrt_is_user_center_page(): bool {
|
||||
return (bool) get_query_var('aksrt_user_center')
|
||||
|| (is_page_template('templates/pages/page-profile.php') && !(bool) get_query_var('user_nicename'));
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_is_user_home_page')) :
|
||||
/**
|
||||
* 判断当前是否为公开用户主页
|
||||
*/
|
||||
function aksrt_is_user_home_page(): bool {
|
||||
return (bool) get_query_var('user_nicename')
|
||||
|| is_page_template('templates/pages/page-user-home.php');
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_profile_url')) :
|
||||
/**
|
||||
* 兼容层:获取用户主页 URL
|
||||
*
|
||||
* @deprecated 使用 aksrt_get_user_center_url() 或 aksrt_get_user_home_url() 替代
|
||||
* @param WP_User|int|string|null $user
|
||||
* @return string
|
||||
*/
|
||||
function aksrt_get_profile_url($user = null): string {
|
||||
// 无参调用 → 当前用户主页(公开页)
|
||||
if ($user === null) {
|
||||
return aksrt_get_user_home_url();
|
||||
}
|
||||
return aksrt_get_user_home_url($user);
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_sign_page_url')) :
|
||||
/**
|
||||
* Get the unified auth page URL, with legacy route fallback while the page self-heals.
|
||||
*
|
||||
* @param string $tab
|
||||
* @param array<string, scalar> $args
|
||||
*/
|
||||
function aksrt_get_sign_page_url(string $tab = 'login', array $args = []): string {
|
||||
$tab = aksrt_normalize_auth_tab($tab);
|
||||
|
||||
$legacy_fallbacks = [
|
||||
'login' => home_url('/login/'),
|
||||
'register' => home_url('/register/'),
|
||||
'bind' => home_url('/bind-account/'),
|
||||
'reset-password' => home_url('/reset-password/'),
|
||||
'verify-email' => home_url('/verify-email/'),
|
||||
];
|
||||
|
||||
$page = aksrt_find_template_page('templates/pages/page-sign.php');
|
||||
if (!$page) {
|
||||
aksrt_ensure_template_page('sign');
|
||||
$page = aksrt_find_template_page('templates/pages/page-sign.php');
|
||||
}
|
||||
|
||||
if ($page instanceof WP_Post) {
|
||||
$url = get_permalink($page->ID);
|
||||
$args = ['tab' => $tab] + $args;
|
||||
return add_query_arg($args, $url);
|
||||
}
|
||||
|
||||
$url = $legacy_fallbacks[$tab] ?? home_url('/login/');
|
||||
return !empty($args) ? add_query_arg($args, $url) : $url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether the current request is served by the unified auth experience.
|
||||
*/
|
||||
function aksrt_is_auth_page_request(): bool {
|
||||
return (bool) get_query_var('aksrt_sign')
|
||||
|| is_page_template('templates/pages/page-sign.php')
|
||||
|| is_page_template('templates/pages/page-login.php')
|
||||
|| is_page_template('templates/pages/page-register.php')
|
||||
|| is_page_template('templates/pages/page-bind-account.php')
|
||||
|| is_page_template('templates/pages/page-reset-password.php')
|
||||
|| is_page_template('templates/pages/page-verify-email.php');
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_login_url')) :
|
||||
/** 获取登录页 URL */
|
||||
function aksrt_get_login_url($redirect = '') {
|
||||
$url = aksrt_get_sign_page_url('login');
|
||||
if ($redirect) {
|
||||
$url = add_query_arg('redirect_to', urlencode($redirect), $url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_register_url')) :
|
||||
/** 获取注册页 URL */
|
||||
function aksrt_get_register_url() {
|
||||
return aksrt_get_sign_page_url('register');
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_bind_url')) :
|
||||
/** 获取绑定账号页面 URL */
|
||||
function aksrt_get_bind_url($transient_key = '') {
|
||||
$url = aksrt_get_template_url('bind');
|
||||
if ($transient_key) {
|
||||
$url = add_query_arg('obk', $transient_key, $url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_logout_url')) :
|
||||
/** 获取退出登录 URL */
|
||||
function aksrt_get_logout_url($redirect = '') {
|
||||
$target = $redirect ?: home_url('/');
|
||||
$url = add_query_arg('redirect_to', rawurlencode($target), home_url('/logout/'));
|
||||
return wp_nonce_url($url, 'aksrt-logout');
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_reset_password_url')) :
|
||||
/**
|
||||
* 获取重置密码页面 URL
|
||||
*
|
||||
* @param string $token 主题重置 token(可选,设置密码时需要)
|
||||
* @param int $user_id 用户 ID(可选,设置密码时需要)
|
||||
* @return string
|
||||
*/
|
||||
function aksrt_get_reset_password_url(string $token = '', int $user_id = 0): string {
|
||||
$url = aksrt_get_template_url('reset-password');
|
||||
if ($token !== '' && $user_id > 0) {
|
||||
$url = add_query_arg([
|
||||
'token' => $token,
|
||||
'uid' => $user_id,
|
||||
], $url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_get_verify_email_url')) :
|
||||
/** 获取邮箱验证页面 URL */
|
||||
function aksrt_get_verify_email_url(int $user_id = 0, array $args = []): string {
|
||||
$url = aksrt_get_template_url('verify-email');
|
||||
if ($user_id > 0) {
|
||||
$args['uid'] = $user_id;
|
||||
}
|
||||
if (!empty($args)) {
|
||||
$url = add_query_arg($args, $url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
endif;
|
||||
|
||||
// Notifications live in the same user/ domain; bootstrap also loads it.
|
||||
if (!class_exists('AKSRT_User_Notifications', false) /* procedural module */ && file_exists(dirname(__DIR__) . '/user-notifications.php')) {
|
||||
require_once dirname(__DIR__) . '/user-notifications.php';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user