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

+10 -10
View File
@@ -22,15 +22,15 @@ Exit code `1` means hard contract errors.
| Domain | PHP builder map key | Menu constants file |
|--------|---------------------|---------------------|
| global | `AKSRT_Admin_Schema_Global` | `assets/admin/src/constants/sections/global.js` |
| page_display | `AKSRT_Admin_Schema_Page_Display` | `page-display.js` |
| post_list | `AKSRT_Admin_Schema_Post_List` | `post-list.js` |
| permissions | `AKSRT_Admin_Schema_Permissions` | `permissions.js` |
| users | `AKSRT_Admin_Schema_Users` | `users.js` |
| payment | `AKSRT_Admin_Schema_Payment` | `payment.js` |
| extensions | `AKSRT_Admin_Schema_Extensions` | `extensions.js` |
| tools | `AKSRT_Admin_Schema_Tools` | `tools.js` |
| shop | `AKSRT_Admin_Schema_Shop` | `shop.js` |
| global | `JIO_Admin_Schema_Global` | `assets/admin/src/constants/sections/global.js` |
| page_display | `JIO_Admin_Schema_Page_Display` | `page-display.js` |
| post_list | `JIO_Admin_Schema_Post_List` | `post-list.js` |
| permissions | `JIO_Admin_Schema_Permissions` | `permissions.js` |
| users | `JIO_Admin_Schema_Users` | `users.js` |
| payment | `JIO_Admin_Schema_Payment` | `payment.js` |
| extensions | `JIO_Admin_Schema_Extensions` | `extensions.js` |
| tools | `JIO_Admin_Schema_Tools` | `tools.js` |
| shop | `JIO_Admin_Schema_Shop` | `shop.js` |
## Known custom pages (not schema REST)
@@ -40,7 +40,7 @@ These use dedicated Vue pages + dedicated REST modules:
- Footer: `FooterSettings` + footer settings API
- Permissions capabilities matrix: `PermissionsCapabilities` + `/permissions/capabilities`
- Shop products/orders and other operational tables
- 工单中心: `UsersTicket` + schema `users/ticket` + `aksrt/v1/admin/tickets*`(部门 / 状态 / 预设回复)
- 工单中心: `UsersTicket` + schema `users/ticket` + `jio/v1/admin/tickets*`(部门 / 状态 / 预设回复)
## Deploy checklist
+28 -28
View File
@@ -1,5 +1,5 @@
{
"generated_at": "2026-11-01T05:33:16+00:00",
"generated_at": "2026-11-01T12:02:20+00:00",
"errors": [],
"warnings": [
"customPage tools-update section 'tools/update' not in PHP schema (ok if pure operational page)",
@@ -258,39 +258,39 @@
"entry": true,
"missing_chunks": [],
"chunks": [
"SchemaPage.YNr16Fc9.js",
"SchemaPage.3Ybae3CT.js",
"vendor-vue.CibbKclz.js",
"FaIcon.DB-L86Cm.js",
"useCollapsibleItems.B7EjDmsr.js",
"useCollapsibleItems.CAN-wuru.js",
"vendor-draggable.CJPlJ2VA.js",
"FaIconPicker.BFlucdpY.js",
"shared-api.GLIRMK1p.js",
"FaIconPicker.DKBuH5IK.js",
"shared-api.CBZ9FiMu.js",
"vendor-misc.DkFG_sHo.js",
"AksColorPicker.YAbprujg.js",
"sortable-options.eXkhlrfL.js",
"JioColorPicker.QfaAsnV3.js",
"sortable-options.CCWOkUQx.js",
"level.E3ANSDAX.js",
"badge.ClviT45t.js",
"badge.on0sWygn.js",
"vendor-naive.Dfu2WQKq.js",
"DeferredPage.DbbPIOR7.js",
"NativeOpsRedirect.GFQhzjCJ.js",
"FloatingButtonsSettings.DYWR59AW.js",
"PageHeader.UHsfBDVL.js",
"FooterTabbarSettings.D8ujMgd9.js",
"PostPageSettings.D8BXJ07f.js",
"CommentSettings.1Il-GVqw.js",
"PermissionsCapabilities.DXXFzINq.js",
"CmsCredits.DESOnIkP.js",
"ThemeInfoPage.D5AogccB.js",
"ThemeAuthorizationPage.MnnPj70n.js",
"DocsPage.UUs_OZP9.js",
"UsersVerify.Dab-auoO.js",
"UsersLevel.B-jXEukF.js",
"UsersBadge.DVCEC3QE.js",
"UsersWechatTemplate.DHoNsqm_.js",
"UsersTicket.D5BTFq6U.js",
"ToolsImportExport.C-XhCKwl.js",
"ToolsHealth.DNZ1YaWo.js",
"ToolsUpdate.38p6GYou.js"
"DeferredPage._-8ZQ7kA.js",
"NativeOpsRedirect.DTVj_Lah.js",
"FloatingButtonsSettings.CLcDBw-c.js",
"PageHeader.nyzEkEki.js",
"FooterTabbarSettings.BnJ6cMko.js",
"PostPageSettings.B7UIuzm1.js",
"CommentSettings.C9rwfnvh.js",
"PermissionsCapabilities.DqpqZWmL.js",
"CmsCredits.B6Gorymm.js",
"ThemeInfoPage.D4pAf5Wr.js",
"ThemeAuthorizationPage.dha7vRbS.js",
"DocsPage.DYMdyjJZ.js",
"UsersVerify.DQdIZBGv.js",
"UsersLevel.DGq7yorC.js",
"UsersBadge.Cb8c_4zF.js",
"UsersWechatTemplate.CCecYMLT.js",
"UsersTicket.DfbFcyTe.js",
"ToolsImportExport.BxHqqdz0.js",
"ToolsHealth.DrJqHumh.js",
"ToolsUpdate.rL8TduLs.js"
]
}
}
+7 -7
View File
@@ -4,7 +4,7 @@
Accepted (2026-07-17); **updated 2026-08-02** for Composer PSR-4 root flatten to `src/`.
## Context
Domain folders were frozen after the root→domain move. Theme types then migrated from global `AKSRT_*` + manual `require_once` to real PHP namespaces under `src/` with Composer PSR-4.
Domain folders were frozen after the root→domain move. Theme types then migrated from global `JIO_*` + manual `require_once` to real PHP namespaces under `src/` with Composer PSR-4.
## Decision
@@ -30,22 +30,22 @@ Domain folders were frozen after the root→domain move. Theme types then migrat
### PSR-4 layout
- Composer: `"AKSRT\\": "src/"`
- Namespace `AKSRT\{Domain}\…` ↔ path `src/{Domain}/…`
- Composer: `"Jio\\": "src/"`
- Namespace `Jio\{Domain}\…` ↔ path `src/{Domain}/…`
- One type per file; StudlyCaps filename = short class/trait/interface name
- Nested segments: `Admin\Schema`, `Admin\Native`, `Payment\Gateways`, `Admin\Schema\PostList`
- OAuth stays under `Auth` (`AKSRT\Auth\OAuth`) — no separate `oauth/` tree
- OAuth stays under `Auth` (`Jio\Auth\OAuth`) — no separate `oauth/` tree
- Do not move `TopicPay` / `PlateFollowPay` into `Content` without updating this ADR
- `CreatorRevenue` and `WeChatNotify` stay under `Payment`
### Loader
1. `functions.php` loads `vendor/autoload.php` (Composer: third-party + theme PSR-4)
2. Immediately after, canary `class_exists(\AKSRT\Core\DomainModel::class)` — if missing, `wp_die` with `composer install` / `composer dump-autoload -o` (stale `vendor/` after PSR-4 cutover is the common failure)
2. Immediately after, canary `class_exists(\Jio\Core\DomainModel::class)` — if missing, `wp_die` with `composer install` / `composer dump-autoload -o` (stale `vendor/` after PSR-4 cutover is the common failure)
3. `inc/bootstrap.php` loads helpers + procedural modules (`inc/modules/*`) + core-hooks only
4. Singleton `init()` remains in `functions.php` using FQCNs
Deploy note: `vendor/` is gitignored. After pull/upload, run `composer install --no-dev --optimize-autoloader` (or at least `composer dump-autoload -o`) in the theme root so `autoload_psr4` includes `"AKSRT\\": ["…/src"]`.
Deploy note: `vendor/` is gitignored. After pull/upload, run `composer install --no-dev --optimize-autoloader` (or at least `composer dump-autoload -o`) in the theme root so `autoload_psr4` includes `"Jio\\": ["…/src"]`.
### Procedural (not PSR-4)
@@ -57,5 +57,5 @@ The one-shot `tools/build-psr4-map.php` migrator (and `tools/psr4-map/` artifact
## Out of scope
- Dual-read `class_alias` shims for old `AKSRT_*` global names (rewrite references instead)
- Dual-read `class_alias` shims for old `JIO_*` global names (rewrite references instead)
- Converting all helpers to classes
+3 -3
View File
@@ -182,9 +182,9 @@ function collect_php_schema_sections(string $themeRoot): array {
continue;
}
$section = $km[1];
// Infer domain from filename: class-aksrt-admin-schema-{domain}-{section}.php
// Infer domain from filename: class-jio-admin-schema-{domain}-{section}.php
$base = basename($file, '.php');
$base = preg_replace('/^(class-aksrt-admin-schema-|Schema)/', '', $base);
$base = preg_replace('/^(class-jio-admin-schema-|Schema)/', '', $base);
$parts = explode('-', $base);
// domain may be multi-token (page_display is page-display in menus but page_display in PHP).
// Prefer matching known domains by prefix.
@@ -507,7 +507,7 @@ if (!$build['present']) {
$info[] = 'admin build ok; chunks=' . count($build['chunks']);
}
echo "AKSRT admin contract audit\n";
echo "Jio admin contract audit\n";
echo str_repeat('=', 48) . "\n";
foreach ($info as $line) {
echo "[info] {$line}\n";
+2 -2
View File
@@ -5,7 +5,7 @@
* Catches the fatal "Trait ... not found" class of bug: a trait (or class) nested
* in a `*-traits/` subdirectory is invisible to PSR-4, which resolves by
* namespace alone and never scans subdirectories. src/ classes load via
* `AKSRT\ => src/` (composer.json) — no bootstrap require list — so a misplaced
* `Jio\ => src/` (composer.json) — no bootstrap require list — so a misplaced
* file loads nowhere and fatals the moment its host class compiles.
*
* Usage (from theme root):
@@ -18,7 +18,7 @@ declare(strict_types=1);
$themeRoot = dirname(__DIR__);
$srcRoot = $themeRoot . '/src';
$prefix = 'AKSRT';
$prefix = 'Jio';
$rii = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($srcRoot, FilesystemIterator::SKIP_DOTS)
+8 -8
View File
@@ -47,12 +47,12 @@ if (!function_exists('sanitize_hex_color')) {
require dirname(__DIR__) . '/vendor/autoload.php';
use AKSRT\WidgetSystem\FieldSchema;
use AKSRT\WidgetSystem\PostQuery;
use AKSRT\WidgetSystem\RendererRegistry;
use AKSRT\WidgetSystem\WidgetAreas;
use AKSRT\WidgetSystem\WidgetRegistry;
use AKSRT\WidgetSystem\WidgetTransfer;
use Jio\WidgetSystem\FieldSchema;
use Jio\WidgetSystem\PostQuery;
use Jio\WidgetSystem\RendererRegistry;
use Jio\WidgetSystem\WidgetAreas;
use Jio\WidgetSystem\WidgetRegistry;
use Jio\WidgetSystem\WidgetTransfer;
$errors = [];
$expected = [
@@ -124,7 +124,7 @@ $walk = static function (array $fields, string $owner) use (&$walk, &$errors, $s
};
foreach ($registry as $slug => $definition) {
if ($definition->id_base() !== 'aksrt_widget_' . $slug) {
if ($definition->id_base() !== 'jio_widget_' . $slug) {
$errors[] = $slug . ': invalid id_base.';
}
if (preg_match('/(?:bbs|forum|shop|cart|inventory|shipping)/i', $slug . ' ' . $definition->renderer())) {
@@ -257,7 +257,7 @@ if (str_contains($asset_source, 'cdn.jsdelivr.net')) {
}
$admin_import_sources = (string) file_get_contents($root . '/src/Admin/ImportExportController.php')
. (string) file_get_contents($root . '/src/Admin/ImportExportControllerPart1.php');
foreach (['/widgets/export', '/widgets/import', '/widgets/templates', 'aksrt_widget_templates'] as $legacy_contract) {
foreach (['/widgets/export', '/widgets/import', '/widgets/templates', 'jio_widget_templates'] as $legacy_contract) {
if (str_contains($admin_import_sources, $legacy_contract)) {
$errors[] = 'Legacy widget import/export contract remains: ' . $legacy_contract;
}
+7 -7
View File
@@ -4,8 +4,8 @@
*
* Source: assets/icons/sprite/{key}.svg — one 1024x1024 icon per file.
* The file name (without .svg) is the sprite key used by
* aksrt_icon_markup('zibsvg-{key}') and <use xlink:href="#icon-{key}">.
* Output: assets/js/runtime/svg-icon.js — aksrt_svgs['key'] = '<path…>' map
* jio_icon_markup('zibsvg-{key}') and <use xlink:href="#icon-{key}">.
* Output: assets/js/runtime/svg-icon.js — jio_svgs['key'] = '<path…>' map
* plus the runtime that injects <symbol> definitions into the page.
*
* Usage: node tools/build-svg-sprite.mjs
@@ -59,7 +59,7 @@ for (const file of files) {
errors.push(`${file}: contains a backslash or single quote`);
continue;
}
entries.push(`aksrt_svgs['${key}'] = '${inner}';`);
entries.push(`jio_svgs['${key}'] = '${inner}';`);
}
if (errors.length) {
@@ -74,15 +74,15 @@ function show_svg() {
viewbox = _t.attr('data-viewbox'),
svgclass = _t.attr('data-class'),
svgname = _t.attr('data-svg'),
svg_html = '<svg class="' + svgclass + '" viewBox="' + viewbox + '">' + aksrt_svgs[svgname] + '</svg>';
svg_html = '<svg class="' + svgclass + '" viewBox="' + viewbox + '">' + jio_svgs[svgname] + '</svg>';
_t.html(svg_html);
});
}
!(function () {
var svg = '';
for (let key in aksrt_svgs) {
svg += aksrt_svgs[key] ? '<symbol id="icon-' + key + '" viewBox="0 0 1024 1024">' + aksrt_svgs[key] + '</symbol>' : '';
for (let key in jio_svgs) {
svg += jio_svgs[key] ? '<symbol id="icon-' + key + '" viewBox="0 0 1024 1024">' + jio_svgs[key] + '</symbol>' : '';
}
var i = '<svg id="svg-icons" aria-hidden="true" style="position:absolute;width:0px;height:0px;overflow:hidden;">' + svg + '</svg>';
@@ -92,6 +92,6 @@ function show_svg() {
})(window);
`;
const header = `/* Generated by tools/build-svg-sprite.mjs from assets/icons/sprite/*.svg — do not edit by hand. */\n'use strict';\nvar aksrt_svgs = [];\n`;
const header = `/* Generated by tools/build-svg-sprite.mjs from assets/icons/sprite/*.svg — do not edit by hand. */\n'use strict';\nvar jio_svgs = [];\n`;
writeFileSync(outFile, header + entries.join('\n') + '\n' + runtime);
console.log(`Built ${entries.length} sprite icons -> assets/js/runtime/svg-icon.js`);
+1 -1
View File
@@ -2,7 +2,7 @@
* 支付中心概览专用的 ECharts 按需入口(由 tools/build-pay-charts.mjs 打包)。
*
* 只注册概览页用到的图表与组件,打包为 IIFE 并挂到 window.echarts。
* 产物:assets/js/runtime/libs/echarts-pay.min.js(入库,后台只在 aksrt_pay 页入队)。
* 产物:assets/js/runtime/libs/echarts-pay.min.js(入库,后台只在 jio_pay 页入队)。
*/
import * as echarts from 'echarts/core';
import { LineChart, BarChart, PieChart } from 'echarts/charts';
+1 -1
View File
@@ -161,7 +161,7 @@ $php = <<<PHP
* Generated by tools/generate-fa5-icons.php — do not edit by hand.
* Bare glyph names; the picker composes "fa {fas|far|fab} fa-{name}".
*
* @package AKSRT
* @package Jio
*/
defined('ABSPATH') || exit;
+20 -20
View File
@@ -4,13 +4,13 @@ declare(strict_types=1);
require dirname(__DIR__) . '/tests/widget-system/bootstrap.php';
use AKSRT\WidgetSystem\FieldSchema;
use AKSRT\WidgetSystem\WidgetRegistry;
use Jio\WidgetSystem\FieldSchema;
use Jio\WidgetSystem\WidgetRegistry;
$root = dirname(__DIR__);
$baseline_path = $root . '/.specs/baselines/widget-reference.json';
$baseline = json_decode((string) file_get_contents($baseline_path), true, 512, JSON_THROW_ON_ERROR);
if (($baseline['schema'] ?? '') !== 'aksrt.widget-reference.v1') {
if (($baseline['schema'] ?? '') !== 'jio.widget-reference.v1') {
throw new RuntimeException('Frozen widget reference baseline is invalid.');
}
@@ -41,17 +41,17 @@ $viewports = [
$modes = ['light', 'dark'];
$images = [
'https://fixtures.aksrt.test/media/course-cover-01.jpg',
'https://fixtures.aksrt.test/media/course-cover-02.jpg',
'https://fixtures.aksrt.test/media/course-cover-03.jpg',
'https://fixtures.jio.test/media/course-cover-01.jpg',
'https://fixtures.jio.test/media/course-cover-02.jpg',
'https://fixtures.jio.test/media/course-cover-03.jpg',
];
function fixture_text(string $id, string $slug, int $index): string {
$labels = [
'question' => '购买后可以长期学习吗?',
'answer' => '可以,已购买内容会永久保存在你的学习中心。',
'name' => 'AKSRT 学员 ' . ($index + 1),
'author' => 'AKSRT 学员 ' . ($index + 1),
'name' => 'Jio 学员 ' . ($index + 1),
'author' => 'Jio 学员 ' . ($index + 1),
'role' => '知识产品体验官',
'price' => '¥99',
'value' => (string) (($index + 1) * 1280) . '+',
@@ -59,31 +59,31 @@ function fixture_text(string $id, string $slug, int $index): string {
'heading' => '从入门到精通的系统学习路径',
'description' => '固定内容用于组件 DOM、响应式和视觉差异验收。',
'content' => '结构清晰、案例完整,并持续更新配套资料。',
'title' => 'AKSRT 固定示例 ' . ($index + 1),
'title' => 'Jio 固定示例 ' . ($index + 1),
'text' => '保持好奇,持续创造。',
];
if (isset($labels[$id])) {
return $labels[$id];
}
if (str_contains($id, 'video')) {
return 'https://fixtures.aksrt.test/media/lesson.m3u8';
return 'https://fixtures.jio.test/media/lesson.m3u8';
}
if (str_contains($id, 'url')) {
return 'https://fixtures.aksrt.test/' . $slug . '/' . ($index + 1);
return 'https://fixtures.jio.test/' . $slug . '/' . ($index + 1);
}
if (str_contains($id, 'ids')) {
return str_contains($id, 'term') || str_contains($id, 'category') ? '101,102,103' : '';
}
return 'AKSRT ' . str_replace('_', ' ', $id) . ' ' . ($index + 1);
return 'Jio ' . str_replace('_', ' ', $id) . ' ' . ($index + 1);
}
function fixture_value(array $field, string $slug, int $index, array $images) {
$type = (string) ($field['type'] ?? 'text');
$id = (string) ($field['id'] ?? '');
$default = $field['default'] ?? null;
if ($id === 'title') return 'AKSRT · ' . ucfirst(str_replace('_', ' ', $slug));
if ($id === 'title') return 'Jio · ' . ucfirst(str_replace('_', ' ', $slug));
if ($id === 'subtitle') return '固定内容与交互状态视觉验收';
if ($id === 'title_highlight') return 'AKSRT';
if ($id === 'title_highlight') return 'Jio';
if ($id === 'show_type') return 'all';
if ($id === 'show_id_type' || $id === 'show_ids') return '';
if ($id === 'layout_bg') {
@@ -113,7 +113,7 @@ function fixture_value(array $field, string $slug, int $index, array $images) {
}
return $value;
}
if ($type === 'link') return ['url' => 'https://fixtures.aksrt.test/' . $slug, 'text' => '查看详情', 'target' => ''];
if ($type === 'link') return ['url' => 'https://fixtures.jio.test/' . $slug, 'text' => '查看详情', 'target' => ''];
if ($type === 'upload') return $images[$index % count($images)];
if ($type === 'icon') return 'fa fas fa-graduation-cap';
if ($type === 'color') return '#667eea';
@@ -123,7 +123,7 @@ function fixture_value(array $field, string $slug, int $index, array $images) {
if (in_array($type, ['number', 'spinner', 'slider'], true)) return $default ?? ($field['min'] ?? 1);
if (in_array($type, ['radio', 'button_set', 'select', 'palette'], true)) return $default ?? (array_key_first((array) ($field['options'] ?? [])) ?? '');
if ($type === 'checkbox') return $default ?? [];
if ($id === 'title_link') return ['url' => 'https://fixtures.aksrt.test/' . $slug, 'text' => '查看更多', 'target' => ''];
if ($id === 'title_link') return ['url' => 'https://fixtures.jio.test/' . $slug, 'text' => '查看更多', 'target' => ''];
if ($default !== null && $default !== '') return $default;
return fixture_text($id, $slug, $index);
}
@@ -159,7 +159,7 @@ foreach (WidgetRegistry::all() as $slug => $definition) {
'reference' => ['file' => $source, 'sha256' => $reference_hashes[$source] ?? ''],
'field_ids' => array_values(array_filter(array_map(static fn(array $field): string => (string) ($field['id'] ?? ''), $definition->fields()))),
'settings' => $settings,
'root_selector' => '[data-aksrt-widget="' . $slug . '"]',
'root_selector' => '[data-jio-widget="' . $slug . '"]',
'states' => array_values(array_unique($states)),
];
foreach ($viewports as $viewport) {
@@ -176,7 +176,7 @@ foreach (WidgetRegistry::all() as $slug => $definition) {
}
$fixture = [
'schema' => 'aksrt.widget-golden.v1',
'schema' => 'jio.widget-golden.v1',
'captured_at' => (string) ($baseline['captured_at'] ?? ''),
'reference' => [
'source_root' => $reference_root,
@@ -194,7 +194,7 @@ $fixture = [
'reduced_motion_required' => true,
],
'dataset' => [
'site' => ['name' => 'AKSRT 知识库', 'url' => 'https://fixtures.aksrt.test'],
'site' => ['name' => 'Jio 知识库', 'url' => 'https://fixtures.jio.test'],
'terms' => [
['id' => 101, 'taxonomy' => 'category', 'name' => '产品设计', 'count' => 24],
['id' => 102, 'taxonomy' => 'category', 'name' => '前端开发', 'count' => 36],
@@ -218,7 +218,7 @@ $fixture = [
['id' => 402, 'user' => 202, 'post' => 302, 'content' => '对主题工程化讲解得很完整。'],
],
'payment_states' => ['guest-locked', 'member-locked', 'free', 'purchased', 'vip-authorized', 'unconfigured'],
'media' => ['images' => $images, 'video' => 'https://fixtures.aksrt.test/media/lesson.m3u8'],
'media' => ['images' => $images, 'video' => 'https://fixtures.jio.test/media/lesson.m3u8'],
],
'components' => $components,
'screenshot_matrix' => $matrix,
+9 -9
View File
@@ -41,7 +41,7 @@ function createModal() {
const autoFunHandlers = new Map();
const body = { classList: createClassList() };
const chargeButton = createButton();
const transferButton = createButton({ 'data-aksrt-transfer-open': 'balance' });
const transferButton = createButton({ 'data-jio-transfer-open': 'balance' });
const chargeModal = createModal();
const transferModal = createModal();
let contentInjected = false;
@@ -50,22 +50,22 @@ const documentStub = {
body,
querySelector(selector) {
if (!contentInjected) return null;
if (selector === '[data-aksrt-charge-modal]') return chargeModal;
if (selector === '[data-aksrt-transfer-modal]') return transferModal;
if (selector === '[data-jio-charge-modal]') return chargeModal;
if (selector === '[data-jio-transfer-modal]') return transferModal;
return null;
},
querySelectorAll(selector) {
if (!contentInjected) return [];
if (selector === '[data-aksrt-charge-open]') return [chargeButton];
if (selector === '[data-aksrt-transfer-open]') return [transferButton];
if (selector === '[data-jio-charge-open]') return [chargeButton];
if (selector === '[data-jio-transfer-open]') return [transferButton];
return [];
},
};
globalThis.document = documentStub;
globalThis.window = {
aksrtData: {},
AksrtRequest: {
jioData: {},
JioRequest: {
request() { return Promise.resolve({ ok: false, json: {} }); },
},
};
@@ -81,10 +81,10 @@ const testFile = fileURLToPath(new URL('../assets/js/credits.js', import.meta.ur
const source = readFileSync(testFile, 'utf8');
new Function(source)();
assert.ok(autoFunHandlers.has('auto_fun.aksrt-credits'), 'credits.js should own one namespaced auto_fun subscription');
assert.ok(autoFunHandlers.has('auto_fun.jio-credits'), 'credits.js should own one namespaced auto_fun subscription');
contentInjected = true;
const rehydrateCredits = autoFunHandlers.get('auto_fun.aksrt-credits');
const rehydrateCredits = autoFunHandlers.get('auto_fun.jio-credits');
rehydrateCredits();
rehydrateCredits();
+3 -3
View File
@@ -4,13 +4,13 @@ declare(strict_types=1);
require dirname(__DIR__) . '/tests/widget-system/bootstrap.php';
use AKSRT\WidgetSystem\WidgetRegistry;
use Jio\WidgetSystem\WidgetRegistry;
$root = dirname(__DIR__);
$fixture_path = $root . '/tests/fixtures/widget-golden-v1.json';
$fixture = json_decode((string) file_get_contents($fixture_path), true, 512, JSON_THROW_ON_ERROR);
$errors = [];
if (($fixture['schema'] ?? '') !== 'aksrt.widget-golden.v1') $errors[] = 'Invalid golden fixture schema.';
if (($fixture['schema'] ?? '') !== 'jio.widget-golden.v1') $errors[] = 'Invalid golden fixture schema.';
$components = (array) ($fixture['components'] ?? []);
$matrix = (array) ($fixture['screenshot_matrix'] ?? []);
if (array_keys($components) !== array_keys(WidgetRegistry::all()) || count($components) !== 37) $errors[] = 'Golden fixture must contain the exact 37 registry widgets.';
@@ -36,7 +36,7 @@ if ($require_results) {
$errors[] = 'Visual result manifest is missing.';
} else {
$result = json_decode((string) file_get_contents($result_path), true, 512, JSON_THROW_ON_ERROR);
if (($result['schema'] ?? '') !== 'aksrt.widget-visual-results.v1') $errors[] = 'Invalid visual result schema.';
if (($result['schema'] ?? '') !== 'jio.widget-visual-results.v1') $errors[] = 'Invalid visual result schema.';
$screenshots = (array) ($result['screenshots'] ?? []);
foreach ($matrix as $id => $expected) {
$actual = (array) ($screenshots[$id] ?? []);
+19 -19
View File
@@ -1,12 +1,12 @@
<?php
/**
* Reversible WP-CLI visual fixtures for AKSRT/Zibll comparison.
* Reversible WP-CLI visual fixtures for Jio/Zibll comparison.
*
* Usage:
* wp eval-file wp-content/themes/AKSRT-theme/tools/wp-cli-visual-fixtures.php create
* wp eval-file wp-content/themes/AKSRT-theme/tools/wp-cli-visual-fixtures.php cleanup
* wp eval-file wp-content/themes/Jio-theme/tools/wp-cli-visual-fixtures.php create
* wp eval-file wp-content/themes/Jio-theme/tools/wp-cli-visual-fixtures.php cleanup
*
* @package AKSRT
* @package Jio
*/
defined('ABSPATH') || exit;
@@ -16,8 +16,8 @@ if (!defined('WP_CLI') || !WP_CLI) {
}
$fixture_action = sanitize_key((string) ($args[0] ?? ''));
$fixture_option = 'aksrt_visual_fixture_manifest_v1';
$fixture_prefix = 'aksrt_zibll_v1_';
$fixture_option = 'jio_visual_fixture_manifest_v1';
$fixture_prefix = 'jio_zibll_v1_';
$fixture_theme_dir = dirname(__DIR__);
$fixture_json = $fixture_theme_dir . '/tests/fixtures/widget-golden-v1.json';
@@ -72,11 +72,11 @@ $cleanup = static function (array $manifest) use ($fixture_option): void {
$existing = get_option($fixture_option, []);
if ($fixture_action === 'cleanup') {
if (!is_array($existing) || empty($existing)) {
WP_CLI::success('No AKSRT visual fixtures found.');
WP_CLI::success('No Jio visual fixtures found.');
return;
}
$cleanup($existing);
WP_CLI::success('AKSRT visual fixtures removed.');
WP_CLI::success('Jio visual fixtures removed.');
return;
}
@@ -126,7 +126,7 @@ try {
$login = $fixture_prefix . 'user_' . ((int) $index + 1);
$user_id = wp_insert_user([
'user_login' => $login,
'user_pass' => 'AKSRT-Visual-2026!',
'user_pass' => 'Jio-Visual-2026!',
'user_email' => $login . '@example.test',
'display_name' => (string) ($source['name'] ?? $login),
'role' => 'subscriber',
@@ -137,10 +137,10 @@ try {
$user_id = (int) $user_id;
$user_map[(int) ($source['id'] ?? 0)] = $user_id;
$manifest['users'][] = $user_id;
update_user_meta($user_id, 'aksrt_points', (int) ($source['points'] ?? 0));
update_user_meta($user_id, 'jio_points', (int) ($source['points'] ?? 0));
if ($index === 0) {
update_user_meta($user_id, 'aksrt_vip_level', 2);
update_user_meta($user_id, 'aksrt_vip_expires', time() + YEAR_IN_SECONDS);
update_user_meta($user_id, 'jio_vip_level', 2);
update_user_meta($user_id, 'jio_vip_expires', time() + YEAR_IN_SECONDS);
}
}
@@ -181,7 +181,7 @@ try {
'post_status' => 'publish',
'post_type' => 'post',
'post_author' => (int) ($user_map[(int) ($source['author'] ?? 0)] ?? 1),
'post_excerpt' => '用于 AKSRT 与 Zibll 同内容视觉比较的固定摘要。',
'post_excerpt' => '用于 Jio 与 Zibll 同内容视觉比较的固定摘要。',
'post_content' => '<h2>视觉基线标题</h2><p>固定正文内容,用于检查排版、目录、付费状态和响应式布局。</p>',
], true);
if (is_wp_error($post_id)) {
@@ -198,14 +198,14 @@ try {
set_post_thumbnail($post_id, (int) $manifest['attachments'][$index % count($manifest['attachments'])]);
}
$pay_type = sanitize_key((string) ($source['pay_type'] ?? 'no'));
$pay = class_exists('AKSRT\\Core\\DomainModel') ? \AKSRT\Core\DomainModel::default_pay_meta() : [];
$pay = class_exists('Jio\\Core\\DomainModel') ? \Jio\Core\DomainModel::default_pay_meta() : [];
$pay['pay_type'] = $pay_type;
$pay['price'] = $pay_type === 'no' ? 0 : 19.9 + $index;
$pay['pay_limit'] = $pay_type === 'vip' ? 1 : 0;
update_post_meta($post_id, '_aksrt_pay', $pay);
update_post_meta($post_id, '_aksrt_pay_type', $pay_type);
update_post_meta($post_id, '_aksrt_pay_price', $pay['price']);
update_post_meta($post_id, 'aksrt_post_views', 1200 + ($index * 137));
update_post_meta($post_id, '_jio_pay', $pay);
update_post_meta($post_id, '_jio_pay_type', $pay_type);
update_post_meta($post_id, '_jio_pay_price', $pay['price']);
update_post_meta($post_id, 'jio_post_views', 1200 + ($index * 137));
}
$no_image = wp_insert_post([
@@ -248,7 +248,7 @@ try {
}
wp_set_sidebars_widgets($sidebars);
update_option($fixture_option, $manifest, false);
WP_CLI::success('Created reversible AKSRT visual fixtures. Login password: AKSRT-Visual-2026!');
WP_CLI::success('Created reversible Jio visual fixtures. Login password: Jio-Visual-2026!');
} catch (Throwable $error) {
$cleanup($manifest);
WP_CLI::error('Fixture creation rolled back: ' . $error->getMessage());