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

@@ -28,7 +28,7 @@ function input(html, name) {
return match[0];
}
function fieldset(html, dependency) {
const tags = [...html.matchAll(/<fieldset\b[^>]*data-aksrt-inv-dep="([^"]+)"[^>]*>/g)];
const tags = [...html.matchAll(/<fieldset\b[^>]*data-jio-inv-dep="([^"]+)"[^>]*>/g)];
const found = tags.find(([, value]) => value === dependency);
assert.ok(found, `missing conditional fieldset ${dependency}`);
return found[0];
@@ -42,18 +42,18 @@ function hasBooleanAttr(tag, name) {
test('filters, selection, table and pagination share one list card', () => {
const { html } = harness();
const cards = [...html.matchAll(/<section\b[^>]*class="[^"]*\baksrt-native-card\b[^"]*"[^>]*>[\s\S]*?<\/section>/g)];
const cards = [...html.matchAll(/<section\b[^>]*class="[^"]*\bjio-native-card\b[^"]*"[^>]*>[\s\S]*?<\/section>/g)];
assert.equal(cards.length, 1);
const card = cards[0][0];
assert.match(card, /aksrt-inv-list-card/);
assert.match(card, /<h2 class="aksrt-native-card__title">邀请码列表<\/h2>/);
for (const marker of ['class="subsubsub"', 'class="aksrt-native-filters"', '清除筛选', 'data-aksrt-inv-selection', 'aksrt-inv-table', 'class="tablenav bottom"']) {
assert.match(card, /jio-inv-list-card/);
assert.match(card, /<h2 class="jio-native-card__title">邀请码列表<\/h2>/);
for (const marker of ['class="subsubsub"', 'class="jio-native-filters"', '清除筛选', 'data-jio-inv-selection', 'jio-inv-table', 'class="tablenav bottom"']) {
assert.ok(card.includes(marker), `${marker} belongs to the list card`);
}
// 批量操作行同时带共享的 aksrt-native-bulk 类,按 class 列表中的词匹配,不要求整串相等。
assert.match(card, /class="[^"]*\baksrt-inv-bulk\b[^"]*"/, 'aksrt-inv-bulk belongs to the list card');
assert.doesNotMatch(html, /aksrt-inv-filter-summary|关键词:/);
assert.doesNotMatch(read('assets', 'css', 'admin', 'invite-codes.css'), /aksrt-inv-filter-summary/);
// 批量操作行同时带共享的 jio-native-bulk 类,按 class 列表中的词匹配,不要求整串相等。
assert.match(card, /class="[^"]*\bjio-inv-bulk\b[^"]*"/, 'jio-inv-bulk belongs to the list card');
assert.doesNotMatch(html, /jio-inv-filter-summary|关键词:/);
assert.doesNotMatch(read('assets', 'css', 'admin', 'invite-codes.css'), /jio-inv-filter-summary/);
});
test('search and bulk actions remain independent sibling forms inside the list card', () => {
@@ -71,8 +71,8 @@ test('search and bulk actions remain independent sibling forms inside the list c
}
assert.equal(depth, 0);
assert.equal(count, 4);
const searchEnd = html.indexOf('</form>', html.indexOf('class="aksrt-native-filters"'));
const listStart = html.lastIndexOf('<form', html.indexOf('data-aksrt-inv-list'));
const searchEnd = html.indexOf('</form>', html.indexOf('class="jio-native-filters"'));
const listStart = html.lastIndexOf('<form', html.indexOf('data-jio-inv-list'));
assert.ok(searchEnd < listStart);
const listEnd = html.indexOf('</form>', listStart);
assert.ok(html.indexOf('class="tablenav bottom"', listStart) < listEnd);
@@ -81,13 +81,13 @@ test('search and bulk actions remain independent sibling forms inside the list c
test('page renders add and export dialogs beside, not inside, the list form', () => {
const { html } = harness();
const listMarker = html.indexOf('data-aksrt-inv-list');
const listMarker = html.indexOf('data-jio-inv-list');
assert.ok(listMarker > 0, 'list form is rendered');
const listStart = html.lastIndexOf('<form', listMarker);
const listEnd = html.indexOf('</form>', listMarker);
const addStart = html.indexOf('<dialog', html.indexOf('id="aksrt-inv-add"') - 100);
const addDialog = dialog(html, 'aksrt-inv-add');
const exportDialog = dialog(html, 'aksrt-inv-export');
const addStart = html.indexOf('<dialog', html.indexOf('id="jio-inv-add"') - 100);
const addDialog = dialog(html, 'jio-inv-add');
const exportDialog = dialog(html, 'jio-inv-export');
const addIndex = html.indexOf(addDialog);
const exportIndex = html.indexOf(exportDialog);
assert.ok(listStart >= 0 && listEnd > listStart);
@@ -100,18 +100,18 @@ test('page renders add and export dialogs beside, not inside, the list form', ()
test('all admin forms carry the expected method, action, and escaped nonce', () => {
const { html } = harness();
const list = html.slice(html.lastIndexOf('<form', html.indexOf('data-aksrt-inv-list')), html.indexOf('</form>', html.indexOf('data-aksrt-inv-list')) + 7);
const add = dialog(html, 'aksrt-inv-add');
const exportForm = dialog(html, 'aksrt-inv-export');
const list = html.slice(html.lastIndexOf('<form', html.indexOf('data-jio-inv-list')), html.indexOf('</form>', html.indexOf('data-jio-inv-list')) + 7);
const add = dialog(html, 'jio-inv-add');
const exportForm = dialog(html, 'jio-inv-export');
assert.match(list, /<form method="post" action="https:\/\/example\.test\/wp-admin\/admin-post\.php"/);
assert.match(list, /name="action" value="aksrt_invite_delete"/);
assert.match(list, /name="action" value="jio_invite_delete"/);
for (const form of [list, add, exportForm]) {
assert.match(form, /name="aksrt_nonce" value="nonce&quot;&lt;script&gt;&amp;"/);
assert.match(form, /name="jio_nonce" value="nonce&quot;&lt;script&gt;&amp;"/);
}
assert.match(add, /<form method="post" action="https:\/\/example\.test\/wp-admin\/admin-post\.php"/);
assert.match(add, /name="action" value="aksrt_invite_add"/);
assert.match(add, /name="action" value="jio_invite_add"/);
assert.match(exportForm, /<form method="get" action="https:\/\/example\.test\/wp-admin\/admin-post\.php"/);
assert.match(exportForm, /name="action" value="aksrt_invite_export"/);
assert.match(exportForm, /name="action" value="jio_invite_export"/);
});
test('rendered code, notice, user, date, and row values are escaped', () => {
@@ -162,20 +162,20 @@ test('numeric fields expose browser constraints and VIP days apply to both level
test('export UI and service consistently name the spreadsheet format CSV', () => {
const { html } = harness();
const exportForm = dialog(html, 'aksrt-inv-export');
const exportForm = dialog(html, 'jio-inv-export');
assert.match(exportForm, /name="export_format" value="csv" checked/);
assert.match(exportForm, /Excel 表格(\.csv)/);
assert.match(exportForm, /文本文档(\.txt)/);
const service = read('src', 'Payment', 'InviteCode.php');
assert.match(service, /\$_GET\['export_format'\] \?\? 'csv'\) === 'text' \? 'text' : 'csv'/);
assert.match(service, /\[__\('邀请码', 'aksrt'\), __\('使用奖励', 'aksrt'\), __\('创建时间', 'aksrt'\), __\('更新时间', 'aksrt'\), __\('状态', 'aksrt'\), __\('标识', 'aksrt'\)\]/);
assert.match(service, /aksrt-invite-codes\.csv/);
assert.match(service, /\[__\('邀请码', 'jio'\), __\('使用奖励', 'jio'\), __\('创建时间', 'jio'\), __\('更新时间', 'jio'\), __\('状态', 'jio'\), __\('标识', 'jio'\)\]/);
assert.match(service, /jio-invite-codes\.csv/);
assert.doesNotMatch(service, /\bxls\b|export_format[^\n]*xls/);
});
test('search form and filter links preserve sanitized keyword and remark context', () => {
const { html } = harness();
const marker = html.indexOf('class="aksrt-native-filters"');
const marker = html.indexOf('class="jio-native-filters"');
const start = html.lastIndexOf('<form', marker);
const end = html.indexOf('</form>', marker);
const form = html.slice(start, end + 7);
@@ -210,7 +210,7 @@ test('page uses no list/add/export tab route and service returns to the canonica
const page = read('src', 'Admin', 'Native', 'UsersMenusInviteCode.php');
const forms = read('src', 'Admin', 'Native', 'UsersMenusInviteForms.php');
assert.doesNotMatch(page + forms + html, /page-title-action|[?&](?:tab|view)=(?:list|add|export)|tab=(?:list|add|export)/);
assert.equal(return_url, 'https://example.test/wp-admin/users.php?page=aksrt_invite_codes');
assert.equal(return_url, 'https://example.test/wp-admin/users.php?page=jio_invite_codes');
assert.doesNotMatch(return_url, /(?:tab|view|add)=/);
});
@@ -229,9 +229,9 @@ test('invite CSS and JS are enqueued only for the invite submenu hook', () => {
assert.deepEqual(wrong_hook_assets, []);
assert.equal(page_assets.length, 2);
assert.deepEqual(page_assets[0].slice(0, 4), [
'style', 'aksrt-admin-invite-codes', 'https://example.test/theme/assets/css/admin/invite-codes.css', ['aksrt-admin-native-ui'],
'style', 'jio-admin-invite-codes', 'https://example.test/theme/assets/css/admin/invite-codes.css', ['jio-admin-native-ui'],
]);
assert.deepEqual(page_assets[1].slice(0, 4), [
'script', 'aksrt-admin-invite-codes', 'https://example.test/theme/assets/js/admin-invite-codes.js', [],
'script', 'jio-admin-invite-codes', 'https://example.test/theme/assets/js/admin-invite-codes.js', [],
]);
});