Register commerce rewrite aliases and special-template bootstrap so /orders loads page-orders even when no page is assigned; flush rules.
527 lines
16 KiB
PHP
527 lines
16 KiB
PHP
<?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/',
|
|
],
|
|
// Commerce center pages (权益与消费 / 购物车 / 收益)
|
|
'orders' => [
|
|
'file' => 'templates/pages/page-orders.php',
|
|
'slug' => 'orders',
|
|
'title' => '我的订单',
|
|
'fallback' => '/orders/',
|
|
],
|
|
'cart' => [
|
|
'file' => 'templates/pages/page-cart.php',
|
|
'slug' => 'cart',
|
|
'title' => '购物车',
|
|
'fallback' => '/cart/',
|
|
],
|
|
'revenue' => [
|
|
'file' => 'templates/pages/page-revenue.php',
|
|
'slug' => 'revenue',
|
|
'title' => '收益中心',
|
|
'fallback' => '/revenue/',
|
|
],
|
|
];
|
|
|
|
/** @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_orders')) {
|
|
$orders_template = aksrt_locate_template_file('templates/pages/page-orders.php');
|
|
return $orders_template ?: '';
|
|
}
|
|
|
|
if (get_query_var('aksrt_cart')) {
|
|
$cart_template = aksrt_locate_template_file('templates/pages/page-cart.php');
|
|
return $cart_template ?: '';
|
|
}
|
|
|
|
if (get_query_var('aksrt_revenue')) {
|
|
$revenue_template = aksrt_locate_template_file('templates/pages/page-revenue.php');
|
|
return $revenue_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();
|
|
}
|
|
}
|
|
|