Files
wordpress-theme-aksrt/inc/modules/user-parts/routing.php
T

287 lines
10 KiB
PHP

<?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[] = 'aksrt_user_center_tab';
$vars[] = 'aksrt_author_identifier';
$vars[] = 'aksrt_orders';
$vars[] = 'aksrt_revenue';
return $vars;
});
add_action('template_redirect', function () {
if (is_admin() || wp_doing_ajax() || is_feed() || is_embed() || is_preview()) {
return;
}
$request_path = trim((string) parse_url($_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH), '/');
if ($request_path === 'profile' || str_starts_with($request_path, 'profile/')) {
global $wp_query;
if ($wp_query instanceof WP_Query) { $wp_query->set_404(); }
status_header(404);
nocache_headers();
return;
}
$resolved_path = aksrt_get_current_special_template_path();
if ($resolved_path === '') {
return;
}
status_header(200);
load_template($resolved_path, true);
exit;
}, 100);
// /user/{tab} only accepts registered user-center tabs; former public /user/{slug}
// addresses must not silently resolve to the user-center home.
add_action('template_redirect', function () {
if (is_admin() || wp_doing_ajax()) {
return;
}
$tab = (string) get_query_var('aksrt_user_center_tab');
if ($tab === '') {
return;
}
$tab = $tab === 'balance' ? 'credits' : sanitize_key($tab);
$allowed = class_exists('\\AKSRT\\User\\Center')
? array_keys(\AKSRT\User\Center::get_instance()->get_dashboard_tabs())
: ['profile', 'level', 'creator', 'comments', 'favorites', 'credits', 'vip', 'orders', 'auth', 'revenue', 'settings'];
if (!in_array($tab, $allowed, true)) {
global $wp_query;
if ($wp_query instanceof WP_Query) { $wp_query->set_404(); }
status_header(404);
nocache_headers();
}
}, 1);
add_action('init', function () {
add_rewrite_tag('%aksrt_user_center%', '([^&]+)');
add_rewrite_tag('%aksrt_user_center_tab%', '([^/]+)');
add_rewrite_tag('%aksrt_author_identifier%', '([^/]+)');
add_rewrite_tag('%aksrt_orders%', '([0-1])');
add_rewrite_tag('%aksrt_revenue%', '([0-1])');
add_rewrite_rule('^user/([a-z0-9_-]+)/?$', 'index.php?aksrt_user_center=1&aksrt_user_center_tab=$matches[1]', 'top');
add_rewrite_rule('^author/([^/]+)/?$', 'index.php?aksrt_author_identifier=$matches[1]', 'top');
// Commerce center aliases (work even before WP page is assigned).
add_rewrite_rule('^orders/?$', 'index.php?aksrt_orders=1', 'top');
add_rewrite_rule('^revenue/?$', 'index.php?aksrt_revenue=1', 'top');
});
// --- 3b. 统一模板拦截器(核心)---
// 拦截所有使用主题特殊模板的页面请求,确保正确加载
add_filter('template_include', function ($template) {
$resolved_path = aksrt_get_current_special_template_path();
if ($resolved_path !== '') {
return $resolved_path;
}
// A) /user/{昵称} even if special-path helper returned empty (user missing → 404).
$identifier = (string) get_query_var('aksrt_author_identifier');
if ($identifier !== '') {
$user = function_exists('aksrt_resolve_public_user') ? aksrt_resolve_public_user($identifier) : null;
if ($user instanceof WP_User) {
$tpl = aksrt_locate_template_file('templates/pages/page-user-home.php');
if ($tpl) {
global $aksrt_profile_user;
$aksrt_profile_user = $user;
return $tpl;
}
}
// Unknown nicename: force 404 instead of blank page.
global $wp_query;
if ($wp_query instanceof WP_Query) {
$wp_query->set_404();
status_header(404);
nocache_headers();
}
$four = get_query_template('404');
return $four ?: $template;
}
// B) ordinary assigned page templates.
if (is_page()) {
$page_id = get_queried_object_id();
if ($page_id) {
$slug = (string) get_post_field('post_name', $page_id);
$page_template = get_post_meta($page_id, '_wp_page_template', true);
if (is_string($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:检查并创建缺失页面(含 profile 用户中心)
$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) {
aksrt_ensure_template_page($key);
}
if ($pages_bootstrapped !== AKSRT_VERSION) {
update_option('aksrt_template_pages_bootstrapped', AKSRT_VERSION);
}
} elseif ($requested_template_key !== '') {
aksrt_ensure_template_page($requested_template_key);
}
// 统一 flush 检查 — bump when user-home rewrite / author override changes
$rewrite_version = AKSRT_VERSION . ':user-center-author-routing-v6';
$flushed = get_option('aksrt_user_rules_flushed');
$rules = get_option('rewrite_rules');
$need_flush = ($flushed !== $rewrite_version)
|| !is_array($rules)
|| $rules === []
|| !get_option('permalink_structure');
// Dev/plain installs often have empty permalink_structure → pretty /user/ 404s at Apache.
// Force a usable structure so registered rewrite rules actually apply.
if (!get_option('permalink_structure')) {
update_option('permalink_structure', '/%postname%/');
$need_flush = true;
}
if ($need_flush) {
flush_rewrite_rules(true);
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(); });
// ============================================================
// 六、作者链接改写 — 强制覆盖 WP 默认 /author/{slug}/
// ============================================================
add_filter('author_link', function ($link, $author_id) {
$author_id = (int) $author_id;
if ($author_id > 0 && function_exists('aksrt_get_user_home_url')) {
return aksrt_get_user_home_url($author_id);
}
$user = get_userdata($author_id);
$slug = $user ? $user->user_nicename : ('user-' . max(0, $author_id));
if (!get_option('permalink_structure')) {
return add_query_arg('aksrt_author', rawurlencode($slug), home_url('/'));
}
return home_url('/author/' . trailingslashit($slug));
}, 99, 2);
// Accept ?user_nicename= when pretty rewrites are unavailable.
add_filter('request', function ($query_vars) {
if (empty($query_vars['aksrt_author_identifier']) && !empty($_GET['aksrt_author'])) {
$query_vars['aksrt_author_identifier'] = sanitize_text_field(wp_unslash((string) $_GET['aksrt_author']));
}
if (empty($query_vars['aksrt_user_center']) && isset($_GET['aksrt_user_center'])) {
$query_vars['aksrt_user_center'] = '1';
}
return $query_vars;
});
// Pretty-permalink author archives → public user home.
add_action('template_redirect', function () {
if (is_admin() || wp_doing_ajax() || is_feed() || is_embed()) {
return;
}
if (!is_author()) {
return;
}
$author_id = (int) get_queried_object_id();
if ($author_id <= 0) {
$author_id = (int) get_query_var('author');
}
if ($author_id <= 0) {
return;
}
$target = function_exists('aksrt_get_user_home_url')
? aksrt_get_user_home_url($author_id)
: home_url('/user/');
if ($target === '' || $target === home_url('/')) {
return;
}
wp_safe_redirect($target, 301);
exit;
}, 1);
// Catch bare ?author=ID when is_author() did not fire.
add_action('template_redirect', function () {
if (is_admin() || wp_doing_ajax()) {
return;
}
if (empty($_GET['author'])) {
return;
}
if (get_query_var('aksrt_author_identifier') || get_query_var('aksrt_user_center')) {
return;
}
if (is_author()) {
return; // handled above
}
$author_id = (int) $_GET['author'];
if ($author_id > 0 && function_exists('aksrt_get_user_home_url')) {
wp_safe_redirect(aksrt_get_user_home_url($author_id), 301);
exit;
}
}, 2);
// ============================================================
// AJAX: 保存用户个人资料(显示名称、简介、联系方式)