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>
This commit is contained in:
kate522andClaude Opus 5 committed 2026-11-01 20:05:04 +08:00
1 parent 5b16bc6e15
commit 35bb96e82f
997 files changed
+28216 -28188

No files matched your search

@@ -1,7 +1,7 @@
'use strict';
/**
* 消息管理后台(users.php → aksrt_messages)契约:
* 消息管理后台(users.php → jio_messages)契约:
* 1) 页面由独立 trait 承载,UsersMenus 只做组合与路由注册;
* 2) 写操作走 admin_post + nonce + 能力校验;
* 3) SQL 全部在 NotificationAdminQuery 内且经 prepare;
@@ -20,25 +20,25 @@ const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
test('messages page is composed from its own trait', () => {
const menus = read('src/Admin/Native/UsersMenus.php');
assert.ok(menus.includes('use UsersMenusMessages;'));
assert.ok(menus.includes("'aksrt_messages'"));
assert.ok(menus.includes("add_action('admin_post_aksrt_users_send_message', [$this, 'handle_send_message'])"));
assert.ok(menus.includes("add_action('admin_post_aksrt_users_bulk_messages', [$this, 'handle_bulk_messages'])"));
assert.ok(menus.includes("'jio_messages'"));
assert.ok(menus.includes("add_action('admin_post_jio_users_send_message', [$this, 'handle_send_message'])"));
assert.ok(menus.includes("add_action('admin_post_jio_users_bulk_messages', [$this, 'handle_bulk_messages'])"));
assert.ok(menus.includes("add_action('admin_enqueue_scripts', [$this, 'enqueue_message_assets'])"));
// 旧实现不得残留在壳类中。
assert.doesNotMatch(menus, /function render_messages_page|function handle_send_message|message_sent|message_failed/);
assert.doesNotMatch(menus, /aksrt_notification/);
assert.doesNotMatch(menus, /jio_notification/);
});
test('write handlers check capability and nonce', () => {
const page = read('src/Admin/Native/UsersMenusMessages.php');
assert.match(page, /function handle_send_message\(\): void \{\s*\$this->ensure_cap\(\);\s*check_admin_referer\('aksrt_users_send_message'\);/);
assert.match(page, /function handle_bulk_messages\(\): void \{\s*\$this->ensure_cap\(\);\s*check_admin_referer\('aksrt_users_bulk_messages'\);/);
assert.match(page, /function handle_send_message\(\): void \{\s*\$this->ensure_cap\(\);\s*check_admin_referer\('jio_users_send_message'\);/);
assert.match(page, /function handle_bulk_messages\(\): void \{\s*\$this->ensure_cap\(\);\s*check_admin_referer\('jio_users_bulk_messages'\);/);
const compose = read('src/Admin/Native/UsersMenusMessagesCompose.php');
const list = read('src/Admin/Native/UsersMenusMessagesList.php');
assert.ok(page.includes('use UsersMenusMessagesCompose;'));
assert.ok(page.includes('use UsersMenusMessagesList;'));
assert.ok(compose.includes("wp_nonce_field('aksrt_users_send_message')"));
assert.ok(list.includes("wp_nonce_field('aksrt_users_bulk_messages')"));
assert.ok(compose.includes("wp_nonce_field('jio_users_send_message')"));
assert.ok(list.includes("wp_nonce_field('jio_users_bulk_messages')"));
// 页面层不直接碰数据库,分页走共享组件。
assert.doesNotMatch(page + compose + list, /\$wpdb/);
assert.ok(page.includes('AdminListPagination::render('));
@@ -53,7 +53,7 @@ test('admin query keeps SQL prepared and bulk size capped', () => {
});
test('dead notification helpers are removed', () => {
assert.doesNotMatch(read('inc/modules/user-notifications.php'), /aksrt_notification_type_label/);
assert.doesNotMatch(read('inc/modules/user-notifications.php'), /jio_notification_type_label/);
assert.doesNotMatch(read('src/Messages/Message.php'), /get_all_notifications/);
assert.ok(fs.existsSync(path.join(root, 'assets/css/admin/messages.css')));
});
@@ -72,10 +72,10 @@ test('list toolbar is merged into the table card and inline confirmation is remo
const page = read('src/Admin/Native/UsersMenusMessages.php');
const list = read('src/Admin/Native/UsersMenusMessagesList.php');
assert.ok(page.indexOf("NativeUi::card_open(__('站内通知'") < page.indexOf('$this->render_message_filter_form'));
assert.doesNotMatch(page + list, /onclick=|confirm\(|<details|aksrt-native-toolbar/);
assert.doesNotMatch(page + list, /onclick=|confirm\(|<details|jio-native-toolbar/);
const { table, empty } = harness();
assert.match(table, /data-aksrt-msg-action="delete" disabled/);
assert.match(table, /data-aksrt-msg-selection/);
assert.match(table, /data-jio-msg-action="delete" disabled/);
assert.match(table, /data-jio-msg-selection/);
assert.match(table, /name="period" value="today"/);
assert.match(empty, /当前筛选条件下没有消息/);
});
@@ -89,27 +89,27 @@ test('message row actions live only in a dedicated rightmost operations column',
const cells = [...row.matchAll(/<(?:th|td)\b[^>]*>[\s\S]*?<\/(?:th|td)>/g)].map(([cell]) => cell);
assert.equal(cells.length, 7);
assert.match(cells[1], /class="column-title"/);
assert.doesNotMatch(cells[1], /<button|data-aksrt-msg-view|data-aksrt-msg-action/);
assert.doesNotMatch(cells[1], /<button|data-jio-msg-view|data-jio-msg-action/);
assert.match(cells[5], /class="column-time"/);
assert.match(cells[6], /class="column-actions"/);
assert.match(cells[6], /data-aksrt-msg-view=/);
assert.match(cells[6], /data-aksrt-msg-action="delete"/);
assert.match(cells[6], /data-jio-msg-view=/);
assert.match(cells[6], /data-jio-msg-action="delete"/);
});
assert.match(empty, /colspan="7"/);
const css = read('assets/css/admin/messages.css');
assert.match(css, /\.aksrt-messages-admin \.aksrt-messages-admin__table \.column-actions\s*\{[^}]*padding-left:\s*20px;[^}]*padding-right:\s*20px;[^}]*text-align:\s*center;/);
assert.match(css, /\.aksrt-msg-row-actions\s*\{[^}]*justify-content:\s*center;/);
assert.match(css, /\.jio-messages-admin \.jio-messages-admin__table \.column-actions\s*\{[^}]*padding-left:\s*20px;[^}]*padding-right:\s*20px;[^}]*text-align:\s*center;/);
assert.match(css, /\.jio-msg-row-actions\s*\{[^}]*justify-content:\s*center;/);
});
test('details preserve full content, escape HTML and unsafe links, and never mark read', () => {
const { table, cache_calls } = harness();
assert.match(table, /<template id="aksrt-msg-detail-8">/);
assert.match(table, /<template id="jio-msg-detail-8">/);
assert.match(table, /完整内容(?:完整内容){99}/);
assert.match(table, /&lt;script&gt;x&lt;\/script&gt;/);
assert.doesNotMatch(table, /<script>|href="javascript:/);
assert.match(table, /2026-10-30 11:30/);
assert.match(table, /查看详情不会改变收件人的已读状态/);
assert.equal((table.match(/data-aksrt-msg-action="mark_read" data-id=/g) || []).length, 1);
assert.equal((table.match(/data-jio-msg-action="mark_read" data-id=/g) || []).length, 1);
assert.deepEqual(cache_calls, [[7]]);
});
@@ -122,8 +122,8 @@ test('role choices display counts and disable only empty or oversized roles', ()
assert.doesNotMatch(compose, /value="contributor"[^>]* disabled/);
assert.match(compose, /data-count-limit="191"/);
assert.match(compose, /data-count-limit="2000"/);
assert.match(compose, /aria-describedby="aksrt-msg-content-count"/);
assert.match(compose, /data-aksrt-msg-pane="role" hidden/);
assert.match(compose, /aria-describedby="jio-msg-content-count"/);
assert.match(compose, /data-jio-msg-pane="role" hidden/);
});
test('overview links, status tabs, filter forms and mutations preserve period filtering', () => {
@@ -157,7 +157,7 @@ test('role broadcasts require confirmation of the current role and count on the
const { send, cap_checked, nonce_checked } = harness();
['unconfirmed', 'changed_count', 'changed_role', 'too_large', 'long_title'].forEach((key) => {
assert.equal(send[key].sent, 0, key);
assert.equal(send[key].redirect.aksrt_msg, 'send_failed', key);
assert.equal(send[key].redirect.jio_msg, 'send_failed', key);
});
assert.equal(send.confirmed.sent, 3);
assert.equal(send.users.sent, 1);
@@ -176,7 +176,7 @@ test('asset types use Chinese labels in filters, row badges and details', () =>
for (const [type, [label]] of Object.entries(asset_types)) {
assert.ok(filter_form.includes(`<option value="${type}">${label}</option>`));
}
assert.match(asset_table, /class="aksrt-msg-badge is-success"[^>]*>余额增加<\/a>/);
assert.match(asset_table, /class="jio-msg-badge is-success"[^>]*>余额增加<\/a>/);
assert.match(asset_table, /<dt>消息类型<\/dt><dd>余额增加<\/dd>/);
});