Files
wordpress-theme-aksrt/inc/modules/user-parts/routing.php
T
kate522andClaude Opus 5 35bb96e82f refactor: rename the theme brand and every identifier from AKSRT to Jio
Full-project rename. `git grep -i aksrt` is now empty apart from the
DBMigrator 3.3.0 changelog note that documents the rename itself.

Code identifiers
- PHP namespace AKSRT\ -> Jio\ (composer PSR-4 + 378 declarations)
- global constants AKSRT_* -> JIO_* (VERSION/DIR/URI, PAY_TYPE_*, CAPTCHA_*)
- procedural functions, hooks, options, meta keys, table names,
  cookies, query vars, ajax actions and nonces: aksrt_ -> jio_
- text domain aksrt -> jio; Theme Name -> Jio
- JS globals: aksrtData/aksrtAdminData/... -> jioData/jioAdminData/...,
  window.AKSRTCaptcha & friends -> window.JioCaptcha, Aksrt* -> Jio*
- Vue components Aks*.vue -> Jio*.vue (15 files renamed + imports)
- CSS classes/data-attrs/custom properties: aksrt- -> jio-
- REST namespace aksrt/v1 -> jio/v1 (incl. payment gateway callbacks)

Storage layer
- DB tables {prefix}aksrt_* -> {prefix}jio_*; SCHEMA_VERSION 3.2.0 -> 3.3.0
  so dbDelta creates the new names on install
- widget id_base aksrt_widget_* -> jio_widget_*
- uninstall.php drop list rebuilt from the actual migrator tables
  (dropped 3 stale entries, added the 17 missing ones)

Removed
- hardcoded https://api.aksrt.com/version.json default update endpoint;
  get_endpoint() now reads the 「更新端点」 setting and do_check() no-ops
  when it is empty

Files renamed: inc/helpers/aksrt-*.php -> jio-*.php (54),
assets/admin/src/components/form/Aks*.vue -> Jio*.vue (15).
Build artifacts regenerated: assets/css/build, assets/js/runtime,
assets/admin/build.

Verified: audit-psr4-paths errors=0, audit-admin-contracts errors=0
(warnings=56, unchanged baseline), 813/813 widget-system tests,
44/44 phpunit, php -l clean across all PHP.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-11-01 20:05:04 +08:00

292 lines
10 KiB
PHP

<?php
/**
* User rewrite/routing/bootstrap flush + author redirects
*
* @package Jio
*/
defined('ABSPATH') || exit;
// ============================================================
// 三、URL 路由与模板加载
// ============================================================
// --- 3a. /user/{昵称} 自定义重写 ---
add_filter('query_vars', function ($vars) {
$vars[] = 'jio_user_center';
$vars[] = 'jio_user_center_tab';
$vars[] = 'jio_author_identifier';
$vars[] = 'jio_message_view';
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;
}
if (!get_query_var('jio_message_view') && is_page() && get_page_template_slug(get_queried_object_id()) === 'templates/pages/page-messages.php') {
global $wp_query;
if ($wp_query instanceof WP_Query) { $wp_query->set_404(); }
status_header(404);
nocache_headers();
return;
}
$resolved_path = jio_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('jio_user_center_tab');
if ($tab === '') {
return;
}
$tab = $tab === 'balance' ? 'credits' : sanitize_key($tab);
$allowed = class_exists('\\Jio\\User\\Center')
? array_keys(\Jio\User\Center::get_instance()->get_dashboard_tabs())
: ['profile', 'level', 'creator', 'posts', 'follow', 'comments', 'favorites', 'credits', 'vip', 'orders', 'auth', 'revenue', 'msg', '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('%jio_user_center%', '([^&]+)');
add_rewrite_tag('%jio_user_center_tab%', '([^/]+)');
add_rewrite_tag('%jio_author_identifier%', '([^/]+)');
add_rewrite_tag('%jio_message_view%', '(unread|posts|like|system)');
$message_slug = preg_quote(jio_get_messages_rewrite_slug(), '#');
add_rewrite_rule('^' . $message_slug . '/?$', 'index.php?jio_message_view=unread', 'top');
add_rewrite_rule('^' . $message_slug . '/(posts|like|system)/?$', 'index.php?jio_message_view=$matches[1]', 'top');
add_rewrite_rule('^user/([a-z0-9_-]+)/?$', 'index.php?jio_user_center=1&jio_user_center_tab=$matches[1]', 'top');
add_rewrite_rule('^author/([^/]+)/?$', 'index.php?jio_author_identifier=$matches[1]', 'top');
});
// --- 3b. 统一模板拦截器(核心)---
// 拦截所有使用主题特殊模板的页面请求,确保正确加载
add_filter('template_include', function ($template) {
$resolved_path = jio_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('jio_author_identifier');
if ($identifier !== '') {
$user = function_exists('jio_resolve_public_user') ? jio_resolve_public_user($identifier) : null;
if ($user instanceof WP_User) {
$tpl = jio_locate_template_file('templates/pages/page-user-home.php');
if ($tpl) {
global $jio_profile_user;
$jio_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 = jio_locate_template_file($page_template);
if ($tpl) {
return $tpl;
}
}
}
}
return $template;
}, 99);
add_filter('template_include', function ($template) {
$resolved_path = jio_get_current_special_template_path();
if ($resolved_path !== '') {
return $resolved_path;
}
if (get_query_var('jio_user_center')) {
$profile_template = jio_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 = jio_resolve_page_template_file(
is_string($page_template) ? $page_template : '',
(string) get_post_field('post_name', $page_id)
);
if ($resolved_template !== '') {
$resolved_path = jio_locate_template_file($resolved_template);
if ($resolved_path) {
return $resolved_path;
}
}
}
}
return $template;
}, 100);
// ============================================================
// 四、自动维护 + flush
// ============================================================
add_action('init', function () {
global $_jio_special_templates;
// 后台/AJAX:检查并创建缺失页面(含 profile 用户中心)
$pages_bootstrapped = get_option('jio_template_pages_bootstrapped');
$requested_template_key = (!is_admin() && !wp_doing_ajax()) ? jio_get_requested_template_key() : '';
if (is_admin() || wp_doing_ajax() || $pages_bootstrapped !== JIO_VERSION) {
foreach ($_jio_special_templates as $key => $cfg) {
jio_ensure_template_page($key);
}
if ($pages_bootstrapped !== JIO_VERSION) {
update_option('jio_template_pages_bootstrapped', JIO_VERSION);
}
} elseif ($requested_template_key !== '') {
jio_ensure_template_page($requested_template_key);
}
// 统一 flush 检查 — bump when user-home rewrite / author override changes
$rewrite_version = JIO_VERSION . ':message-routing:' . jio_get_messages_rewrite_slug();
$flushed = get_option('jio_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('jio_user_rules_flushed', $rewrite_version);
}
});
// 页面变更时清缓存
add_action('save_post', function ($pid) { if (get_post_type($pid) === 'page') jio_clear_template_page_cache(); });
add_action('delete_post', function ($pid) { if (get_post_type($pid) === 'page') jio_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('jio_get_user_home_url')) {
return jio_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('jio_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['jio_author_identifier']) && !empty($_GET['jio_author'])) {
$query_vars['jio_author_identifier'] = sanitize_text_field(wp_unslash((string) $_GET['jio_author']));
}
if (empty($query_vars['jio_user_center']) && isset($_GET['jio_user_center'])) {
$query_vars['jio_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('jio_get_user_home_url')
? jio_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('jio_author_identifier') || get_query_var('jio_user_center')) {
return;
}
if (is_author()) {
return; // handled above
}
$author_id = (int) $_GET['author'];
if ($author_id > 0 && function_exists('jio_get_user_home_url')) {
wp_safe_redirect(jio_get_user_home_url($author_id), 301);
exit;
}
}, 2);
// ============================================================
// AJAX: 保存用户个人资料(显示名称、简介、联系方式)