Files
wordpress-theme-aksrt/src/Core/ScriptsPart2.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

278 lines
9.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* @package Jio
*/
namespace Jio\Core;
defined('ABSPATH') || exit;
trait ScriptsPart2 {
/**
* 前端 debug 上报入口(仅在 WP_DEBUG 模式下写日志)
*/
public function handle_frontend_debug(): void {
check_ajax_referer('jio_public_nonce', 'nonce');
if (!defined('WP_DEBUG') || !WP_DEBUG) {
wp_send_json_success(['ignored' => true]);
}
$ctx = [
'source' => isset($_POST['source']) ? sanitize_text_field(wp_unslash($_POST['source'])) : 'frontend',
'event' => isset($_POST['event']) ? sanitize_text_field(wp_unslash($_POST['event'])) : 'unknown',
'page' => isset($_POST['page']) ? esc_url_raw(wp_unslash($_POST['page'])) : '',
'text' => isset($_POST['text']) ? sanitize_text_field(wp_unslash($_POST['text'])) : '',
'size' => isset($_POST['size']) ? (int) wp_unslash($_POST['size']) : 0,
'error' => isset($_POST['error']) ? sanitize_text_field(wp_unslash($_POST['error'])) : '',
];
$this->debug_log('frontend debug event', $ctx);
wp_send_json_success(['logged' => true]);
}
/**
* 加载后台资源 — 仅在 Jio 设置页面加载(与前端样式完全隔离)
*/
public function enqueue_admin($hook): void {
// 只在 Jio 设置页面 (SPA 容器) 加载
$screen = get_current_screen();
if (!$screen || $screen->base !== 'toplevel_page_jio-settings') {
return;
}
// Admin 专用面板样式 — 独立于前端,不受前端 CSS 影响
wp_enqueue_style(
'jio-admin-panel',
JIO_URI . '/assets/css/admin/admin-panel.css',
[], // 无依赖,不加载任何前端样式
JIO_VERSION
);
// 注意: SPA 主资源 (Vue3 build) 由 \Jio\Admin\Admin::enqueue_admin_assets() 负责加载
}
/**
* 输出运行时 CSS 变量覆盖
*
* 仅注入用户可在后台配置的覆盖值(logo / favicon / primary),
* 主体宽度统一使用固定 token:1280 / 1080 / 300。
*/
public function inline_css_vars(): void {
(new \Jio\Frontend\InlineStyleBuilder())->output();
}
/**
* 输出自定义头部/底部代码
*/
public function output_custom_codes(): void {
(new \Jio\Frontend\CustomCodeRenderer())->output_header();
}
public function output_loading_overlay(): void {
(new \Jio\Frontend\LoadingOverlayRenderer())->output();
}
/**
* 输出自定义底部代码
*/
public function output_custom_footer_codes(): void {
(new \Jio\Frontend\CustomCodeRenderer())->output_footer();
}
/**
* Body 类增强
*/
public function body_classes(array $classes): array {
if (is_front_page()) {
$classes[] = 'front-page';
}
if (function_exists('jio_is_fixed_homepage_request') && jio_is_fixed_homepage_request()) {
$classes[] = 'jio-homepage-layout';
$classes[] = 'jio-homepage-active';
}
if (is_singular()) {
$classes[] = 'single-post-' . get_the_ID();
}
if (is_archive()) {
$classes[] = 'archive-page';
}
if ((function_exists('jio_is_user_center_page') && jio_is_user_center_page())
|| (function_exists('jio_is_user_home_page') && jio_is_user_home_page())
|| get_query_var('jio_author_identifier')) {
$classes[] = 'jio-profile';
}
// 区分本人中心与公开主页的 body class
if (function_exists('jio_is_user_center_page') && jio_is_user_center_page()) {
$classes[] = 'jio-user-center';
}
if (function_exists('jio_is_user_home_page') && jio_is_user_home_page()) {
$classes[] = 'jio-user-home';
}
if (function_exists('jio_is_auth_page_request') && jio_is_auth_page_request()) {
$classes[] = 'auth-page';
}
// 对齐参考主题 close_backdrop:fps-accelerat 由 main.css 统一关闭 backdrop-filter。
if (class_exists('\Jio\Settings\Settings') && \Jio\Settings\Settings::close_backdrop()) {
$classes[] = 'fps-accelerat';
}
// legacy site-layout-1/2/3 (no sidebar / right / left).
if (function_exists('jio_body_layout_classes')) {
foreach (jio_body_layout_classes() as $layout_class) {
$classes[] = $layout_class;
}
}
return $classes;
}
/**
* 搜索历史同步(登录用户)
*/
public function handle_search_history(): void {
check_ajax_referer('jio_public_nonce', 'nonce');
$user_id = get_current_user_id();
if (!$user_id) {
wp_send_json_error(['message' => '未登录'], 401);
}
$mode = isset($_POST['mode']) ? sanitize_key(wp_unslash($_POST['mode'])) : 'get';
$meta_key = 'jio_search_history';
if ($mode === 'save') {
$raw = isset($_POST['items']) ? wp_unslash($_POST['items']) : '[]';
$items = json_decode($raw, true);
if (!is_array($items)) {
$items = [];
}
$clean = [];
foreach (array_slice($items, 0, 20) as $item) {
if (!is_array($item) || empty($item['keyword'])) {
continue;
}
$clean[] = [
'keyword' => sanitize_text_field($item['keyword']),
'type' => sanitize_key($item['type'] ?? 'post'),
];
}
update_user_meta($user_id, $meta_key, $clean);
wp_send_json_success(['items' => $clean]);
}
$saved = get_user_meta($user_id, $meta_key, true);
wp_send_json_success(['items' => is_array($saved) ? $saved : []]);
}
/**
* 搜索建议(实时搜索提示)
*/
public function handle_search_suggestions(): void {
check_ajax_referer('jio_public_nonce', 'nonce');
$q = isset($_POST['q']) ? sanitize_text_field(wp_unslash($_POST['q'])) : '';
$type = isset($_POST['type']) ? sanitize_key(wp_unslash($_POST['type'])) : 'post';
if (mb_strlen($q) < 2) {
wp_send_json_success(['items' => []]);
}
$items = [];
if ($type === 'post' || $type === '') {
$posts = get_posts([
'post_type' => 'post',
'post_status' => 'publish',
's' => $q,
'posts_per_page' => 6,
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
]);
foreach ($posts as $p) {
$items[] = [
'title' => $p->post_title,
'url' => get_permalink($p),
'meta' => get_the_date('', $p),
];
}
} elseif ($type === 'category') {
$terms = get_terms([
'taxonomy' => 'category',
'search' => $q,
'number' => 6,
'hide_empty' => true,
]);
if (!is_wp_error($terms)) {
foreach ($terms as $t) {
$items[] = [
'title' => $t->name,
'url' => get_term_link($t),
'meta' => sprintf(__('%d 篇文章', 'jio'), $t->count),
];
}
}
} elseif ($type === 'tag') {
$terms = get_terms([
'taxonomy' => 'post_tag',
'search' => $q,
'number' => 6,
'hide_empty' => true,
]);
if (!is_wp_error($terms)) {
foreach ($terms as $t) {
$items[] = [
'title' => $t->name,
'url' => get_term_link($t),
'meta' => sprintf(__('%d 篇文章', 'jio'), $t->count),
];
}
}
}
wp_send_json_success(['items' => $items]);
}
private function debug_log(string $message, array $context = []): void {
if (!defined('WP_DEBUG') || !WP_DEBUG) {
return;
}
$payload = '[Jio Scripts] ' . $message;
if (!empty($context)) {
$json = wp_json_encode($context, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if (false !== $json) {
$payload .= ' ' . $json;
}
}
error_log($payload);
}
/**
* Resolve public route URLs from the rebuilt mainline ownership.
*
* @return array<string, string>
*/
private function resolve_frontend_routes(): array {
return [
'orders' => function_exists('jio_get_user_center_tab_url') ? jio_get_user_center_tab_url('orders') : home_url('/user/orders/'),
'resources' => home_url('/resources/'),
];
}
/**
* Resolve the permalink for a template-owned page with a stable fallback.
*/
private function resolve_template_page_url(string $template_file, string $fallback): string {
if (function_exists('jio_find_template_page')) {
$page = jio_find_template_page($template_file);
if ($page instanceof \WP_Post) {
return get_permalink($page);
}
}
return home_url($fallback);
}
}