导入 AKSRT 主题开发源码
This commit is contained in:
1 parent
9681dd3d48
commit
1268a55dd0
595 files changed
+127705
No files matched your search
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
/**
|
||||
* AKSRT Theme Admin
|
||||
*
|
||||
* Admin SPA container + legacy REST compatibility façade.
|
||||
* New domain routes live in inc/classes/admin/* controllers, while this class
|
||||
* remains the orchestrator and keeps only shell/bootstrap and public AJAX
|
||||
* helpers that are intentionally centralized.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class AKSRT_Admin {
|
||||
|
||||
private static $instance = null;
|
||||
private const PAGE_SLUG = 'aksrt-settings';
|
||||
private const API_NAMESPACE = 'aksrt/v1';
|
||||
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
public function init(): void {
|
||||
add_action('admin_menu', [$this, 'add_admin_menu']);
|
||||
add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']);
|
||||
add_filter('script_loader_tag', [$this, 'add_module_type_attribute'], 10, 2);
|
||||
add_action('rest_api_init', [$this, 'register_rest_routes']);
|
||||
|
||||
add_action('wp_ajax_aksrt_load_more_posts', [$this, 'ajax_load_more_posts']);
|
||||
add_action('wp_ajax_nopriv_aksrt_load_more_posts', [$this, 'ajax_load_more_posts']);
|
||||
add_action('wp_ajax_aksrt_load_more_comments', [$this, 'ajax_load_more_comments']);
|
||||
add_action('wp_ajax_nopriv_aksrt_load_more_comments', [$this, 'ajax_load_more_comments']);
|
||||
}
|
||||
|
||||
public function add_admin_menu(): void {
|
||||
add_menu_page(
|
||||
'AKSRT 主题设置',
|
||||
'AKSRT',
|
||||
'manage_options',
|
||||
self::PAGE_SLUG,
|
||||
[$this, 'render_admin_page'],
|
||||
'dashicons-admin-generic',
|
||||
58
|
||||
);
|
||||
}
|
||||
|
||||
public function render_admin_page(): void {
|
||||
echo '<div class="wrap aksrt-admin-wrap">';
|
||||
echo '<div id="aksrt-admin-app"></div>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
public function enqueue_admin_assets($hook): void {
|
||||
$screen = function_exists('get_current_screen') ? get_current_screen() : null;
|
||||
if (!$screen || $screen->base !== 'toplevel_page_' . self::PAGE_SLUG) {
|
||||
return;
|
||||
}
|
||||
|
||||
$build_dir = trailingslashit(AKSRT_DIR) . 'assets/admin/build/';
|
||||
$build_uri = trailingslashit(AKSRT_URI) . 'assets/admin/build/';
|
||||
|
||||
$css_files = [
|
||||
'naive-ui.css',
|
||||
'index.css',
|
||||
'index2.css',
|
||||
];
|
||||
foreach ($css_files as $css_file) {
|
||||
$path = $build_dir . $css_file;
|
||||
if (file_exists($path)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-admin-' . sanitize_key(str_replace(['.', '/'], '-', $css_file)),
|
||||
$build_uri . $css_file,
|
||||
[],
|
||||
(string) filemtime($path)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$entry = $build_dir . 'index.js';
|
||||
if (file_exists($entry)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-admin-app',
|
||||
$build_uri . 'index.js',
|
||||
[],
|
||||
(string) filemtime($entry),
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script('aksrt-admin-app', 'aksrtAdminData', [
|
||||
'apiUrl' => esc_url_raw(rest_url(self::API_NAMESPACE)),
|
||||
'nonce' => wp_create_nonce('wp_rest'),
|
||||
'siteUrl' => home_url('/'),
|
||||
'adminUrl' => admin_url('/'),
|
||||
'themeVersion' => wp_get_theme()->get('Version') ?: '3.4.0-dev',
|
||||
]);
|
||||
}
|
||||
|
||||
wp_enqueue_media();
|
||||
}
|
||||
|
||||
public function add_module_type_attribute(string $tag, string $handle): string {
|
||||
if ('aksrt-admin-app' === $handle) {
|
||||
return str_replace('<script ', '<script type="module" ', $tag);
|
||||
}
|
||||
return $tag;
|
||||
}
|
||||
|
||||
public function register_rest_routes(): void {
|
||||
$controllers = [
|
||||
'AKSRT_Admin_Global_Controller',
|
||||
'AKSRT_Admin_Page_Display_Controller',
|
||||
'AKSRT_Admin_Post_List_Controller',
|
||||
'AKSRT_Admin_Permissions_Controller',
|
||||
'AKSRT_Admin_User_Controller',
|
||||
'AKSRT_Admin_Payment_Controller',
|
||||
'AKSRT_Admin_Tools_Controller',
|
||||
'AKSRT_Admin_Import_Export_Controller',
|
||||
'AKSRT_Admin_Shop_Controller',
|
||||
'AKSRT_Admin_Forum_Controller',
|
||||
'AKSRT_Admin_Extension_Controller',
|
||||
'AKSRT_Admin_Comment_Controller',
|
||||
'AKSRT_Admin_Message_Controller',
|
||||
'AKSRT_Admin_AI_Controller',
|
||||
];
|
||||
|
||||
foreach ($controllers as $class_name) {
|
||||
if (!class_exists($class_name) || !method_exists($class_name, 'get_instance')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$controller = $class_name::get_instance();
|
||||
if (method_exists($controller, 'register_routes')) {
|
||||
$controller->register_routes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function sanitize_public_query_vars(array $vars): array {
|
||||
$allowed = [
|
||||
'post_type', 'post_status', 'posts_per_page', 'paged', 'orderby', 'order',
|
||||
'cat', 'tag', 'tag_id', 'category_name', 's', 'post__not_in', 'category__not_in',
|
||||
];
|
||||
$clean = [];
|
||||
foreach ($allowed as $key) {
|
||||
if (!array_key_exists($key, $vars)) {
|
||||
continue;
|
||||
}
|
||||
$value = $vars[$key];
|
||||
if (is_array($value)) {
|
||||
$clean[$key] = array_map('sanitize_text_field', $value);
|
||||
} else {
|
||||
$clean[$key] = sanitize_text_field((string) $value);
|
||||
}
|
||||
}
|
||||
if (isset($clean['posts_per_page'])) {
|
||||
$clean['posts_per_page'] = max(1, min(50, (int) $clean['posts_per_page']));
|
||||
}
|
||||
if (isset($clean['paged'])) {
|
||||
$clean['paged'] = max(1, (int) $clean['paged']);
|
||||
}
|
||||
return $clean;
|
||||
}
|
||||
|
||||
public static function sanitize_public_render_config(array $config): array {
|
||||
$clean = [];
|
||||
if (isset($config['mode'])) {
|
||||
$clean['mode'] = sanitize_key((string) $config['mode']);
|
||||
}
|
||||
if (isset($config['context'])) {
|
||||
$clean['context'] = sanitize_key((string) $config['context']);
|
||||
}
|
||||
if (isset($config['query_context'])) {
|
||||
$clean['query_context'] = sanitize_key((string) $config['query_context']);
|
||||
}
|
||||
return $clean;
|
||||
}
|
||||
|
||||
public function ajax_load_more_posts(): void {
|
||||
check_ajax_referer('aksrt_public_nonce', 'nonce');
|
||||
$page = max(1, (int) ($_POST['page'] ?? 1));
|
||||
$query_vars = json_decode(wp_unslash((string) ($_POST['query_vars'] ?? '{}')), true);
|
||||
$render_config = json_decode(wp_unslash((string) ($_POST['render_config'] ?? '{}')), true);
|
||||
$query_vars = is_array($query_vars) ? self::sanitize_public_query_vars($query_vars) : [];
|
||||
$render_config = is_array($render_config) ? self::sanitize_public_render_config($render_config) : [];
|
||||
$query_vars['paged'] = $page;
|
||||
|
||||
$query = new WP_Query($query_vars);
|
||||
ob_start();
|
||||
if (function_exists('aksrt_render_post_list')) {
|
||||
aksrt_render_post_list($query, $render_config, true);
|
||||
}
|
||||
$html = ob_get_clean();
|
||||
|
||||
wp_send_json_success([
|
||||
'html' => $html,
|
||||
'has_more' => $page < (int) $query->max_num_pages,
|
||||
'page' => $page,
|
||||
]);
|
||||
}
|
||||
|
||||
public function ajax_load_more_comments(): void {
|
||||
check_ajax_referer('aksrt_public_nonce', 'nonce');
|
||||
$post_id = absint($_POST['post_id'] ?? 0);
|
||||
$page = max(1, (int) ($_POST['page'] ?? 1));
|
||||
if ($post_id <= 0) {
|
||||
wp_send_json_error(['message' => __('无效的文章 ID', 'aksrt')]);
|
||||
}
|
||||
|
||||
$settings = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_comment_display_settings() : [];
|
||||
$per_page = max(1, (int) get_option('comments_per_page', 10));
|
||||
$comment_query = new WP_Comment_Query([
|
||||
'post_id' => $post_id,
|
||||
'status' => 'approve',
|
||||
'number' => $per_page,
|
||||
'offset' => ($page - 1) * $per_page,
|
||||
'orderby' => 'comment_date_gmt',
|
||||
'order' => !empty($settings['order']) && strtoupper((string) $settings['order']) === 'ASC' ? 'ASC' : 'DESC',
|
||||
]);
|
||||
$comments = $comment_query->comments;
|
||||
|
||||
ob_start();
|
||||
if (!empty($comments) && function_exists('aksrt_comment_callback')) {
|
||||
set_query_var('aksrt_comment_settings', $settings);
|
||||
wp_list_comments([
|
||||
'callback' => 'aksrt_comment_callback',
|
||||
'style' => 'ul',
|
||||
'avatar_size' => max(24, (int) ($settings['avatar_size'] ?? 48)),
|
||||
'max_depth' => max(1, (int) ($settings['nested_depth'] ?? 3)),
|
||||
], $comments);
|
||||
}
|
||||
$html = ob_get_clean();
|
||||
|
||||
$total = get_comments([
|
||||
'post_id' => $post_id,
|
||||
'status' => 'approve',
|
||||
'count' => true,
|
||||
]);
|
||||
$max_pages = (int) ceil(((int) $total) / $per_page);
|
||||
|
||||
wp_send_json_success([
|
||||
'html' => $html,
|
||||
'has_more' => $page < $max_pages,
|
||||
'page' => $page,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user