refactor: flatten src/AKSRT → src (drop theme-identifier dir)

Move all domain folders from src/AKSRT/{Domain} to src/{Domain}; remap
Composer PSR-4 "AKSRT\\": "src/"; update audit script + README + ADR
paths; remove dead tools/build-psr4-map.php (scanned deleted inc/classes).
This commit is contained in:
2026-08-02 22:06:06 +08:00
parent 56f1a8175f
commit 8c5b1555c9
285 changed files with 26 additions and 3600 deletions
+171
View File
@@ -0,0 +1,171 @@
<?php
/**
* @package AKSRT
*/
namespace AKSRT\Core;
defined('ABSPATH') || exit;
class UpdateChecker {
private static $instance = null;
private const OPTION_KEY = 'aksrt_update_check';
private const CHECK_INTERVAL = DAY_IN_SECONDS * 1; // Check daily
private function __construct() {}
public static function get_instance(): self {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function init(): void {
add_action('admin_init', [$this, 'maybe_check']);
add_action('admin_notices', [$this, 'show_update_notice']);
}
/**
* Get current theme version
*/
private function get_current_version(): string {
$theme = wp_get_theme();
return $theme->get('Version') ?: '0.0.0';
}
/**
* Get update endpoint URL
*/
private function get_endpoint(): string {
if (class_exists('\AKSRT\Settings\Settings')) {
$endpoint = \AKSRT\Settings\Settings::get_value('update_endpoint', '');
if (!empty($endpoint)) return $endpoint;
}
return 'https://api.aksrt.com/version.json';
}
/**
* Maybe check for updates (once per day)
*/
public function maybe_check(): void {
$stored = get_option(self::OPTION_KEY, []);
$last_check = $stored['last_check'] ?? 0;
if ((time() - $last_check) < self::CHECK_INTERVAL) {
return;
}
$this->do_check();
}
/**
* Force check for updates
*/
public function do_check(): void {
$endpoint = $this->get_endpoint();
$response = wp_remote_get($endpoint, [
'timeout' => 5,
'headers' => [
'Accept' => 'application/json',
],
]);
if (is_wp_error($response)) {
update_option(self::OPTION_KEY, [
'last_check' => time(),
'error' => $response->get_error_message(),
]);
return;
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if (!is_array($data) || empty($data['version'])) {
return;
}
$current = $this->get_current_version();
$remote_version = $data['version'];
$update_available = version_compare($remote_version, $current, '>');
update_option(self::OPTION_KEY, [
'last_check' => time(),
'current_version' => $current,
'remote_version' => $remote_version,
'update_available' => $update_available,
'download_url' => $data['download_url'] ?? '',
'changelog' => $data['changelog'] ?? '',
'notify' => !empty($data['notify']),
]);
}
/**
* Show admin notice if update is available
*/
public function show_update_notice(): void {
if (!current_user_can('update_themes')) return;
$stored = get_option(self::OPTION_KEY, []);
if (empty($stored['update_available'])) return;
$remote = $stored['remote_version'] ?? '';
$current = $stored['current_version'] ?? '';
$download_url = $stored['download_url'] ?? '';
$changelog = $stored['changelog'] ?? '';
// User dismissed this version?
$dismissed = get_user_meta(get_current_user_id(), 'aksrt_dismissed_update', true);
if ($dismissed === $remote) return;
$dismiss_url = wp_nonce_url(
add_query_arg('aksrt_dismiss_update', $remote, admin_url()),
'aksrt_dismiss_update_' . $remote
);
echo '<div class="notice notice-info is-dismissible">';
echo '<p><strong>' . esc_html__('AKSRT 主题更新', 'aksrt') . '</strong></p>';
echo '<p>' . sprintf(
esc_html__('新版本 %s 可用(当前版本 %s)。', 'aksrt'),
'<strong>' . esc_html($remote) . '</strong>',
esc_html($current)
) . '</p>';
if (!empty($changelog)) {
echo '<p>' . esc_html($changelog) . '</p>';
}
echo '<p>';
if (!empty($download_url)) {
echo '<a href="' . esc_url($download_url) . '" class="button button-primary" target="_blank">'
. esc_html__('下载更新', 'aksrt') . '</a> ';
}
echo '<a href="' . esc_url($dismiss_url) . '" class="button">'
. esc_html__('忽略此版本', 'aksrt') . '</a>';
echo '</p>';
echo '</div>';
}
/**
* Handle dismiss action
*/
public static function handle_dismiss(): void {
if (!isset($_GET['aksrt_dismiss_update'])) return;
$version = sanitize_text_field($_GET['aksrt_dismiss_update']);
if (!wp_verify_nonce($_GET['_wp_nonce'] ?? '', 'aksrt_dismiss_update_' . $version)) return;
update_user_meta(get_current_user_id(), 'aksrt_dismissed_update', $version);
wp_safe_redirect(remove_query_arg(['aksrt_dismiss_update', '_wp_nonce']));
exit;
}
/**
* Get stored update info
*/
public function get_update_info(): array {
return get_option(self::OPTION_KEY, []);
}
}