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

+239
View File
@@ -0,0 +1,239 @@
<?php
/**
* Jio Slider Helper — 轮播渲染函数
*
* 对标 legacy 的 legacy(),提供服务端轮播 HTML 生成。
* 支持 data-* 属性驱动配置、视差、懒加载、缩略图分页。
*
* @package Jio
*/
defined('ABSPATH') || exit;
/**
* 渲染 Swiper 轮播
*
* @param array $args {
* @type array $slides 幻灯片数据数组
* @type string $effect 动画效果: slide, fade, cube, coverflow, flip (默认 slide)
* @type bool $loop 是否循环 (默认 true)
* @type bool $autoplay 是否自动播放 (默认 true)
* @type int $interval 自动播放间隔 ms (默认 5000)
* @type int $speed 动画速度 ms (0=自动计算)
* @type string $direction 方向: horizontal, vertical (默认 horizontal)
* @type int $spaceBetween 幻灯片间距 px (默认 0)
* @type string $pagination_type 分页器类型: bullets, fraction, progressbar, thumbnail (默认 bullets)
* @type string $pc_height PC 端高度 CSS 值 (默认 auto)
* @type string $m_height 移动端高度 CSS 值 (默认 auto)
* @type bool $scale_height 是否使用比例高度 (默认 false)
* @type float $scale_ratio 比例值 (默认 0.45 = 45%)
* @type string $scale_extra 比例高度附加量,如 '50px'(用于封面标题预留,默认空)
* @type string $wrapper_class 额外 wrapper 类
* @type string $slider_class 额外 slider 类
* @type bool $show_nav 是否显示导航箭头 (默认 true)
* @type bool $show_pagination 是否显示分页器 (默认 true)
* }
*
* slide 数据格式:
* [
* 'image' => 'https://...',
* 'link' => 'https://...',
* 'title' => '标题',
* 'desc' => '描述',
* 'alt' => '图片 alt',
* 'bg_color' => '#f0f0f0', // 背景色
* 'target' => '_blank',
* ]
*
* @return string HTML
*/
function jio_render_slider(array $args = []): string {
$defaults = [
'slides' => [],
'effect' => 'slide',
'loop' => true,
'autoplay' => true,
'interval' => 5000,
'speed' => 0,
'direction' => 'horizontal',
'spaceBetween' => 0,
'pagination_type' => 'bullets',
'pc_height' => 'auto',
'm_height' => 'auto',
'scale_height' => false,
'scale_ratio' => 0.45,
'scale_extra' => '',
'wrapper_class' => '',
'slider_class' => '',
'show_nav' => true,
'show_pagination' => true,
// Optional absolute overlay HTML (e.g. single cover title/meta). Not escaped.
'overlay_html' => '',
];
$args = wp_parse_args($args, $defaults);
$slides = $args['slides'];
if (empty($slides) || !is_array($slides)) {
return '';
}
// 构建 data 属性
$data_attrs = [];
$data_attrs[] = 'data-effect="' . esc_attr($args['effect']) . '"';
if ($args['loop']) $data_attrs[] = 'data-loop';
if ($args['autoplay']) {
$data_attrs[] = 'data-autoplay';
$data_attrs[] = 'data-interval="' . esc_attr((string) $args['interval']) . '"';
}
if ($args['speed'] > 0) $data_attrs[] = 'data-speed="' . esc_attr((string) $args['speed']) . '"';
if ($args['direction'] !== 'horizontal') $data_attrs[] = 'data-direction="' . esc_attr($args['direction']) . '"';
if ($args['spaceBetween'] > 0) $data_attrs[] = 'data-spaceBetween="' . esc_attr((string) $args['spaceBetween']) . '"';
if ($args['pagination_type'] !== 'bullets') $data_attrs[] = 'data-pagination-type="' . esc_attr($args['pagination_type']) . '"';
// 高度样式
$height_style = '';
$scale_padding = '';
if ($args['scale_height']) {
// padding-bottom percentage for ratio box (legacy graphic cover style).
// 内层 .new-swiper 绝对定位铺满 wrapper,wrapper 决定盒子高度;
// pc/m-height 100% 让 .swiper-wrapper/.swiper-slide 铺满盒子,
// 使 object-fit: cover 在确定的盒内居中裁切(对齐单图封面)。
$ratio_pct = max(10, min(100, (float) $args['scale_ratio'] * 100));
$scale_padding = $ratio_pct . '%';
$scale_extra = trim((string) $args['scale_extra']);
if ($scale_extra !== '') {
$scale_padding = 'calc(' . $scale_padding . ' + ' . $scale_extra . ')';
}
$height_style = '--pc-height:100%;--m-height:100%;';
} else {
$height_style = sprintf('--pc-height:%s;--m-height:%s;', esc_attr($args['pc_height']), esc_attr($args['m_height']));
}
// CSS 类
$slider_classes = ['new-swiper', 'slide-index'];
if ($args['slider_class']) $slider_classes[] = $args['slider_class'];
$slider_class_str = implode(' ', $slider_classes);
$wrapper_classes = ['jio-slider-wrapper'];
if ($args['wrapper_class']) $wrapper_classes[] = $args['wrapper_class'];
if ($args['scale_height']) $wrapper_classes[] = 'jio-slider-wrapper--scale';
if ((string) $args['overlay_html'] !== '') $wrapper_classes[] = 'jio-slider-wrapper--has-overlay';
$wrapper_class_str = implode(' ', $wrapper_classes);
// 渲染 HTML
$html = '<div class="' . esc_attr($wrapper_class_str) . '"' . ($args['scale_height'] ? ' style="position:relative;padding-bottom:' . esc_attr($scale_padding) . ';"' : '') . '>';
$html .= '<div class="' . esc_attr($slider_class_str) . '" ' . implode(' ', $data_attrs) . ' style="' . esc_attr($height_style . ($args['scale_height'] ? 'position:absolute;inset:0;width:100%;height:100%;' : '')) . '">';
$html .= '<div class="swiper-wrapper">';
foreach ($slides as $slide) {
$image = esc_url($slide['image'] ?? '');
$link = esc_url($slide['link'] ?? '');
$title = sanitize_text_field($slide['title'] ?? '');
$desc = sanitize_text_field($slide['desc'] ?? '');
$alt = sanitize_text_field($slide['alt'] ?? $title);
$bg_color = \Jio\Core\Color::sanitize($slide['bg_color'] ?? '');
$target = ($slide['target'] ?? '') === '_blank' ? '_blank' : '_self';
$slide_style = $bg_color ? 'background-color:' . esc_attr($bg_color) . ';' : '';
$html .= '<div class="swiper-slide"' . ($slide_style ? ' style="' . esc_attr($slide_style) . '"' : '') . '>';
if ($link) {
$html .= '<a href="' . esc_url($link) . '" target="' . esc_attr($target) . '">';
}
if ($image) {
$html .= '<img' . jio_get_lazy_attr('lazy_sider', (string) $image, 'fit-cover', jio_get_lazy_thumb('lg')) . ' alt="' . esc_attr($alt) . '">';
}
if ($link) {
$html .= '</a>';
}
// 文字覆盖层
if ($title || $desc) {
$html .= '<div class="jio-slide-text">';
if ($title) $html .= '<div class="jio-slide-text__title">' . esc_html($title) . '</div>';
if ($desc) $html .= '<div class="jio-slide-text__desc">' . esc_html($desc) . '</div>';
$html .= '</div>';
}
$html .= '</div>';
}
$html .= '</div>'; // .swiper-wrapper
if ($args['show_nav']) {
$html .= '<div class="swiper-button-prev"></div>';
$html .= '<div class="swiper-button-next"></div>';
}
if ($args['show_pagination']) {
$html .= '<div class="swiper-pagination"></div>';
}
$html .= '</div>'; // .new-swiper
// Cover title/meta overlay (trusted HTML from single cover renderer).
if ((string) $args['overlay_html'] !== '') {
$html .= '<div class="jio-slider-overlay">' . $args['overlay_html'] . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
$html .= '</div>'; // .jio-slider-wrapper
return $html;
}
/**
* 渲染水平滚动器(Tab 导航、横向内容列表)
*
* @param array $args {
* @type array $items 内容数组
* @type string $wrapper_class 额外 wrapper 类
* @type bool $autoplay 是否自动播放
* @type int $interval 自动播放间隔
* @type string $render_item 自定义渲染回调 (callable)
* }
* @return string HTML
*/
function jio_render_scroll_slider(array $args = []): string {
$defaults = [
'items' => [],
'wrapper_class' => '',
'autoplay' => false,
'interval' => 4000,
'render_item' => null,
];
$args = wp_parse_args($args, $defaults);
$items = $args['items'];
if (empty($items)) return '';
$data_attrs = ['class="swiper-scroll' . ($args['wrapper_class'] ? ' ' . esc_attr($args['wrapper_class']) : '') . '"'];
if ($args['autoplay']) {
$data_attrs[] = 'data-autoplay';
$data_attrs[] = 'data-interval="' . esc_attr((string) $args['interval']) . '"';
}
$html = '<div ' . implode(' ', $data_attrs) . '>';
$html .= '<div class="swiper-wrapper">';
foreach ($items as $i => $item) {
$html .= '<div class="swiper-slide">';
if (is_callable($args['render_item'])) {
$html .= call_user_func($args['render_item'], $item, $i);
} else {
$html .= '<div class="jio-scroll-item">' . esc_html($item['label'] ?? '') . '</div>';
}
$html .= '</div>';
}
$html .= '</div>';
$html .= '<div class="swiper-button-prev"></div>';
$html .= '<div class="swiper-button-next"></div>';
$html .= '</div>';
return $html;
}