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

@@ -18,15 +18,15 @@ const settingsFacade = read('src/Settings/Settings.php')
const scriptsPart1c = read('src/Core/ScriptsPart1c.php')
const footerCss = read('assets/css/frontend/footer/shell.css')
const frontendBaseCss = read('assets/css/frontend/base.css')
const headerMenuButtons = read('inc/helpers/aksrt-header-menu-buttons.php')
const headerMenuButtons = read('inc/helpers/jio-header-menu-buttons.php')
const frontendRenderer = read('src/WidgetSystem/FrontendRenderer.php')
const userRenderer = read('src/WidgetSystem/Renderers/UserRenderer.php')
const widgetCss = read('assets/widgets/frontend.css')
const headerNavbar = read('inc/helpers/header/aksrt-header-navbar.php')
const headerMobile = read('inc/helpers/header/aksrt-header-mobile.php')
const headerRender = read('inc/helpers/header/aksrt-header-render.php')
const headerUserbox = read('inc/helpers/aksrt-header-userbox.php')
const headerSearch = read('inc/helpers/header/aksrt-header-menu-search.php')
const headerNavbar = read('inc/helpers/header/jio-header-navbar.php')
const headerMobile = read('inc/helpers/header/jio-header-mobile.php')
const headerRender = read('inc/helpers/header/jio-header-render.php')
const headerUserbox = read('inc/helpers/jio-header-userbox.php')
const headerSearch = read('inc/helpers/header/jio-header-menu-search.php')
const headerCss = read('assets/css/frontend/header-userbox.css')
const coreResetCss = read('assets/css/core/reset.css')
const vipCardRenderer = read('src/Content/VipServiceModal.php')
@@ -119,7 +119,7 @@ test('defaults, nested structures, dependencies, and excluded product families a
assert.equal(schema.includes(dead), false, `legacy/excluded field remains: ${dead}`)
}
assert.equal(headerMenuButtons.includes('nav_newposts_btns'), false)
assert.match(headerMenuButtons, /aksrt_render_new_add_btns\(\['post'\], \$class, \$label\)/)
assert.match(headerMenuButtons, /jio_render_new_add_btns\(\['post'\], \$class, \$label\)/)
// FA5 spelling of the reference '<i class="fa fa-fw fa-pencil"></i>发布'
// default: fa-pencil does not exist in the bundled FA 5.15.4 free set.
assert.match(schema, /'nav_newposts_text', '按钮文案', 'textarea', '<i class="fa fas fa-fw fa-pencil-alt"><\/i>发布'/)
@@ -150,13 +150,13 @@ test('header VIP hover cards match the legacy markup and style contract', () =>
assert.match(headerMenuButtons, /'<a rel="nofollow" class="newadd-btns ' \. esc_attr\(\$class\) \. ' btn-newadd"/)
assert.equal((headerMenuButtons.match(/Settings::close_sign\(\)/g) || []).length, 2)
for (const dead of ['navbar-cta', 'navbar-cta-text', 'navbar-newposts', 'navbar-vip-hover', 'newadd-btns__', 'vip-level', 'fa-gem']) {
assert.equal(headerMenuButtons.includes(dead), false, `AKSRT-only header CTA token remains: ${dead}`)
assert.equal(headerMenuButtons.includes(dead), false, `Jio-only header CTA token remains: ${dead}`)
}
assert.match(vipCardRenderer, /aksrt_get_lazy_attr\('lazy_other', \$icon_url, 'img-icon'\)/)
assert.match(vipCardRenderer, /jio_get_lazy_attr\('lazy_other', \$icon_url, 'img-icon'\)/)
assert.match(vipCardRenderer, /<div class=\"abs-center vip-baicon\"[^>]*>/)
assert.match(vipCardRenderer, /<div class=\"vip-img abs-right\">/)
assert.match(vipCardRenderer, /<div class=\"vip-name mb10\"><span class=\"mr6\">/)
assert.match(vipCardRenderer, /aksrt_format_vip_equity_html\(\$equity, 'mb10 relative'\)/)
assert.match(vipCardRenderer, /jio_format_vip_equity_html\(\$equity, 'mb10 relative'\)/)
assert.doesNotMatch(vipCardRenderer, /vip-name__(?:icon|label)/)
assert.doesNotMatch(vipModalCss, /Header hover VIP cards/)
@@ -178,9 +178,9 @@ test('header VIP hover cards match the legacy markup and style contract', () =>
test('user card VIP CTA matches the reference zib_get_header_payvip_icon()', () => {
assert.match(headerUserbox, /'<a class="pay-vip but radius4 payvip-icon btn-block" href="javascript:;">'/)
assert.match(headerUserbox, /<svg class="em12 mr6" aria-hidden="true"><use xlink:href="#icon-vip_1"><\/use><\/svg>'/)
assert.match(headerUserbox, /esc_html__\('开通会员 尊享会员权益', 'aksrt'\)/)
assert.match(headerUserbox, /esc_html__\('开通会员 尊享会员权益', 'jio'\)/)
for (const dead of ['fa-gem', 'vip-level']) {
assert.equal(headerUserbox.includes(dead), false, `AKSRT-only user card CTA token remains: ${dead}`)
assert.equal(headerUserbox.includes(dead), false, `Jio-only user card CTA token remains: ${dead}`)
}
assert.doesNotMatch(headerUserbox, /<span>' \. esc_html__\('开通会员 尊享会员权益'/)
})
@@ -195,10 +195,10 @@ test('VIP purchase modal matches legacy desktop-center and mobile-bottom positio
// 高度/滚动 = .modal.flex .modal-content 的 max-height calc(100vh - 20px)
// + overflow-y auto(阈值放宽到整屏,正常内容不出现滚动条);
// 圆角 = .modal-content 的 var(--main-radius)(8px)。
assert.match(vipModalCss, /\.aksrt-vip-modal-shell \.aksrt-modal-runtime__dialog\s*\{[\s\S]*?width:\s*min\(600px, calc\(100vw - 20px\)\);[\s\S]*?max-height:\s*calc\(100vh - 20px\);[\s\S]*?overflow:\s*hidden;[\s\S]*?overflow-y:\s*auto;[\s\S]*?border-radius:\s*var\(--main-radius, 8px\);/)
assert.match(vipModalCss, /\.jio-vip-modal-shell \.jio-modal-runtime__dialog\s*\{[\s\S]*?width:\s*min\(600px, calc\(100vw - 20px\)\);[\s\S]*?max-height:\s*calc\(100vh - 20px\);[\s\S]*?overflow:\s*hidden;[\s\S]*?overflow-y:\s*auto;[\s\S]*?border-radius:\s*var\(--main-radius, 8px\);/)
// 内边距由 .box-body 15px 提供(参考主题无 .payvip-modal 专属 padding)。
assert.doesNotMatch(vipModalCss, /\.payvip-modal\s*\{[^}]*padding:/)
assert.match(vipModalCss, /@media \(max-width: 768px\)[\s\S]*?\.aksrt-vip-modal-shell\.aksrt-modal-runtime--bottom \.aksrt-modal-runtime__dialog\s*\{[\s\S]*?width:\s*100%;[\s\S]*?max-height:\s*calc\(100vh - 20px\);[\s\S]*?border-radius:\s*var\(--main-radius, 8px\) var\(--main-radius, 8px\) 0 0;/)
assert.match(vipModalCss, /@media \(max-width: 768px\)[\s\S]*?\.jio-vip-modal-shell\.jio-modal-runtime--bottom \.jio-modal-runtime__dialog\s*\{[\s\S]*?width:\s*100%;[\s\S]*?max-height:\s*calc\(100vh - 20px\);[\s\S]*?border-radius:\s*var\(--main-radius, 8px\) var\(--main-radius, 8px\) 0 0;/)
})
test('schema REST saves are privileged, section-whitelisted, and deeply sanitized', () => {
@@ -231,8 +231,8 @@ test('legacy routes, components, and storage paths are gone', () => {
const repository = activeRepositorySource()
for (const dead of [
'aksrt_footer_settings', 'aksrt_banners', 'aksrt_banner', 'aksrt-banner', 'HomeModules', 'homepage_modules',
'/settings/homepage', 'home-modules', 'cms-home-modules', 'aksrt_preview', 'theme-background',
'jio_footer_settings', 'jio_banners', 'jio_banner', 'jio-banner', 'HomeModules', 'homepage_modules',
'/settings/homepage', 'home-modules', 'cms-home-modules', 'jio_preview', 'theme-background',
"templates/parts/home-modules",
]) {
assert.equal(repository.includes(dead), false, `active legacy implementation remains: ${dead}`)
@@ -278,7 +278,7 @@ test('front-end page-display consumers read only the canonical section contracts
test('footer brand icons keep the Brands font when legacy fa prefix is present', () => {
const footer = read('footer.php')
const icons = read('inc/helpers/aksrt-icons.php')
const icons = read('inc/helpers/jio-icons.php')
assert.match(footer, /class="fa fab fa-weixin"/)
assert.match(footer, /class="fa fab fa-qq"/)
@@ -301,8 +301,8 @@ test('header multifunction search keeps focus and submit alignment route-indepen
test('user profile and author widgets render the reference user-card contract', () => {
assert.match(frontendRenderer, /in_array\(\$definition->slug\(\), \['user_card', 'author_card'\], true\)/)
assert.match(frontendRenderer, /self::render_reference_widget\(\$definition, \$instance, \$widget, \$content\)/)
assert.match(frontendRenderer, /\$classes = \['zib-widget-wrap', 'aksrt-'/)
assert.match(frontendRenderer, /\$classes\[\] = 'aksrt-user-widget-wrap'/)
assert.match(frontendRenderer, /\$classes = \['zib-widget-wrap', 'jio-'/)
assert.match(frontendRenderer, /\$classes\[\] = 'jio-user-widget-wrap'/)
assert.match(frontendRenderer, /echo '<div class="widget-container"><div>';/)
assert.match(frontendRenderer, /\$content_classes = \['widget-content'\]/)
// 登录卡片与 reference zib_get_user_card_box 同构:封面、头像框、名字行、统计徽章、简介、按钮。
@@ -314,17 +314,17 @@ test('user profile and author widgets render the reference user-card contract',
assert.match(userRenderer, /author-tag mt10 mini-scrollbar/)
assert.match(userRenderer, /user-desc mt10 muted-2-color em09/)
assert.match(userRenderer, /user-btns mt20/)
assert.match(userRenderer, /aksrt_get_user_badges\(\$user_id\)/)
assert.match(userRenderer, /jio_get_user_badges\(\$user_id\)/)
assert.match(userRenderer, /'follow' => true,/)
// 用户个人信息小工具不显示文章模块,显示签到徽章。
assert.match(userRenderer, /'show_posts' => false,/)
assert.match(userRenderer, /'show_checkin' => true,/)
assert.match(userRenderer, /aksrt_header_user_checkin_btn\(\$user_id, 'img-badge jb-yellow'\)/)
assert.match(userRenderer, /jio_header_user_checkin_btn\(\$user_id, 'img-badge jb-yellow'\)/)
// 文章作者信息小工具显示文章模块,并走同一 widget 变体。
assert.match(userRenderer, /'show_posts' => !isset\(\$i\['show_posts'\]\) \|\| !empty\(\$i\['show_posts'\]\),/)
assert.match(userRenderer, /'post_type' => 'post',/)
assert.match(userRenderer, /self::card_box\(\(int\) \$user->ID,[\s\S]*?\) \. '<\/div>';/)
assert.match(userRenderer, /aksrt_render_user_card_posts\(/)
assert.match(userRenderer, /jio_render_user_card_posts\(/)
assert.match(userRenderer, /'post_type' => \(string\) \$args\['post_type'\],/)
// 未登录卡片使用主题认证真值和 reference 登录/社交 DOM。
assert.match(userRenderer, /Settings::close_sign\(\)/)
@@ -346,26 +346,26 @@ test('user profile and author widgets render the reference user-card contract',
assert.doesNotMatch(widgetCss, /\.widget-content[^{,]*\{[^}]*padding/s)
assert.doesNotMatch(read('assets/css/frontend/sidebar.css'), /\.widget-content[^{,]*\{[^}]*padding/s)
assert.doesNotMatch(widgetCss, /user-card__auth-btns/)
assert.doesNotMatch(widgetCss, /\.aksrt-user-card\s*\{/)
assert.doesNotMatch(userRenderer, /aksrt-widget-button is-ghost/)
assert.doesNotMatch(widgetCss, /\.jio-user-card\s*\{/)
assert.doesNotMatch(userRenderer, /jio-widget-button is-ghost/)
})
test('desktop header actions share one row without generic button masks', () => {
assert.match(headerNavbar, /navbar-form navbar-right navbar-but/)
assert.match(headerNavbar, /navbar-form navbar-right flex ac/)
assert.match(headerNavbar, /\$fold \. \('3' === \$layout \? \$right_but \. \$button : \$button \. \$right_but\)/)
assert.match(headerNavbar, /class="aksrt-nav-icon nav-search-btn main-search-btn"/)
assert.match(headerNavbar, /class="jio-nav-icon nav-search-btn main-search-btn"/)
assert.doesNotMatch(headerNavbar, /class="btn nav-search-btn main-search-btn"/)
assert.match(headerNavbar, /<ul class="list-inline splitters relative">/)
assert.doesNotMatch(headerNavbar, /aksrt-navbar-account|aksrt-nav-avatar/)
assert.doesNotMatch(headerNavbar, /jio-navbar-account|jio-nav-avatar/)
assert.match(headerNavbar, /class="navbar-avatar"/)
assert.match(legacyMainCss, /\.navbar-avatar\s*\{[^}]*margin-top:\s*3px;[^}]*width:\s*29px;[^}]*height:\s*29px;/s)
assert.match(headerNavbar, /aksrt_get_translate_language_btn\('ml10 pull-right'\)/)
assert.match(headerNavbar, /jio_get_translate_language_btn\('ml10 pull-right'\)/)
assert.match(headerNavbar, /<a data-toggle-class data-target="\.nav\.navbar-nav" href="javascript:;" class="but"/)
assert.match(headerNavbar, /<svg class="icon" viewBox="50 0 924 924"/)
assert.match(headerNavbar, /<svg class="icon" aria-hidden="true"><use xlink:href="#icon-search"/)
assert.doesNotMatch(headerCss, /\.aksrt-navbar-account|\.aksrt-nav-avatar|navbar-form\.flex\.ac\s*\{[^}]*min-height/)
assert.match(headerCss, /\.navbar-top \.aksrt-nav-icon\s*\{[^}]*display:\s*inline-block;[^}]*padding:\s*6px 12px;[^}]*font-size:\s*14px;[^}]*line-height:\s*1\.42857143;[^}]*border:\s*1px solid transparent;[^}]*border-radius:\s*4px;/s)
assert.doesNotMatch(headerCss, /\.jio-navbar-account|\.jio-nav-avatar|navbar-form\.flex\.ac\s*\{[^}]*min-height/)
assert.match(headerCss, /\.navbar-top \.jio-nav-icon\s*\{[^}]*display:\s*inline-block;[^}]*padding:\s*6px 12px;[^}]*font-size:\s*14px;[^}]*line-height:\s*1\.42857143;[^}]*border:\s*1px solid transparent;[^}]*border-radius:\s*4px;/s)
// The publish and VIP chips ride the legacy .but geometry verbatim; nothing in
// the header module may restate their padding, margin, radius or icon size.
// Descendant, not child: the VIP chip lives inside the hover-show wrapper.
@@ -373,7 +373,7 @@ test('desktop header actions share one row without generic button masks', () =>
assert.doesNotMatch(headerCss, /\.navbar-cta|\.navbar-vip-hover/)
// No merged flex container: the three groups keep their own .navbar-form
// padding, which is what produces the reference inter-cluster spacing.
assert.doesNotMatch(headerCss, /\.aksrt-navbar-actions|\.aksrt-navbar-account|\.aksrt-nav-avatar/)
assert.doesNotMatch(headerCss, /\.jio-navbar-actions|\.jio-navbar-account|\.jio-nav-avatar/)
})
test('mobile search follows the reference center and left header placements', () => {
@@ -381,15 +381,15 @@ test('mobile search follows the reference center and left header placements', ()
assert.match(headerNavbar, /mobile_layout/)
assert.match(headerNavbar, /'center' === \(\$ctx\['mobile_layout'\] \?\? 'center'\)/)
assert.match(headerMobile, /main-search-btn|toggle-radius/)
assert.match(headerMobile, /aksrt_nav_mobile_content\(\$ctx\)/)
assert.match(headerMobile, /jio_nav_mobile_content\(\$ctx\)/)
assert.doesNotMatch(headerRender, /'fixed'\s*=>/)
assert.doesNotMatch(legacyMainCss, /\.mobile-navbar \.navbar-(?:header|brand)/)
assert.doesNotMatch(coreResetCss, /img,\s*picture,\s*video,\s*canvas,\s*svg\s*\{/)
assert.match(legacyMainCss, /svg\s*\{[^}]*width:\s*1em;[^}]*height:\s*1em;/s)
const topHeaderSearch = headerRender.indexOf('aksrt_navbar_header($ctx);')
const topHeaderSearch = headerRender.indexOf('jio_navbar_header($ctx);')
const topHeaderClose = headerRender.indexOf("echo '</div></div></nav></header>';")
const mobileDrawer = headerRender.indexOf('aksrt_nav_mobile_shell($ctx);')
const mobileDrawer = headerRender.indexOf('jio_nav_mobile_shell($ctx);')
assert.ok(topHeaderSearch > -1 && topHeaderSearch < topHeaderClose)
assert.ok(topHeaderClose < mobileDrawer)
assert.match(legacyMainCss, /\.scroll-down\.nav-fixed \.header\.scroll-down-hide\s*\{[^}]*transform:\s*translate3d\(0, -105%, 0\);/s)
@@ -417,21 +417,21 @@ test('header user-card membership stays on one row with a date-only expiry', ()
// Reference VIP bar: legacy payvip-icon geometry, the untouched level-icon
// contract, and the yellow expiry pill.
assert.match(headerUserbox, /radius4 payvip-icon btn-block text-center/)
assert.match(headerUserbox, /aksrt_get_vip_icon\(\$user_id, 'em12 mr6', false\)/)
assert.match(headerUserbox, /jio_get_vip_icon\(\$user_id, 'em12 mr6', false\)/)
assert.match(headerUserbox, /class="ml10 badg jb-yellow vip-expdate-tag"/)
assert.match(legacyMainCss, /\.sub-user-box \.payvip-icon\s*\{[^}]*padding:\s*8px;/s)
assert.match(legacyMainCss, /\.vip-expdate-tag\s*\{[^}]*font-size:\s*0\.8em;[^}]*padding:\s*0\.1em 6px;[^}]*vertical-align:\s*0\.1em;/s)
assert.doesNotMatch(vipModalCss, /\.vip-expdate-tag\s*\{/)
assert.doesNotMatch(headerCss, /aksrt-header-payvip/)
assert.doesNotMatch(headerCss, /jio-header-payvip/)
// The CTA wrapper is the reference padding wrapper, not a bespoke hook.
assert.match(headerUserbox, /'<div class="mt10 em09" style="padding:2px;">'/)
assert.doesNotMatch(headerUserbox, /aksrt-header-payvip/)
assert.doesNotMatch(headerUserbox, /jio-header-payvip/)
// Expiry badge follows zib_get_user_vip_exp_date_text(): an expiry that has
// passed reads 会员已过期, a live one reads the bare date, 永久会员 is reserved
// for an explicit permanent membership, and no expiry data renders no badge.
assert.match(headerUserbox, /\$expires <= time\(\)/)
assert.match(headerUserbox, /empty\(\$state\['is_permanent'\]\)/)
assert.doesNotMatch(headerUserbox, /aksrt_get_vip_info/)
assert.doesNotMatch(headerUserbox, /jio_get_vip_info/)
})
test('save contract rejects invalid input and round-trips canonical nested values', () => {