refactor: flatten src/AKSRT → src (drop theme-identifier dir)
Move all domain folders from src/AKSRT/{Domain} to src/{Domain}; remap
Composer PSR-4 "AKSRT\\": "src/"; update audit script + README + ADR
paths; remove dead tools/build-psr4-map.php (scanned deleted inc/classes).
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
/**
|
||||
* Simple image slider widget (zibll widget_ui_slider → aksrt_render_slider / new-swiper).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Widgets;
|
||||
|
||||
use AKSRT\Widgets\Traits\CommonWidgetFields;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class WidgetSlider extends \WP_Widget {
|
||||
use CommonWidgetFields;
|
||||
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(
|
||||
'aksrt_slider',
|
||||
esc_html__('AKSRT 幻灯片', 'aksrt'),
|
||||
[
|
||||
'description' => esc_html__('多图轮播(共享 new-swiper / Swiper 栈),支持链接与标题。', 'aksrt'),
|
||||
'classname' => 'widget_aksrt_slider slide-widget',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function widget($args, $instance): void {
|
||||
$slides = $this->normalize_slides($instance['slides'] ?? []);
|
||||
if (!$slides) {
|
||||
if (current_user_can('manage_options')) {
|
||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo function_exists('aksrt_get_widget_null')
|
||||
? aksrt_get_widget_null(__('当前配置下没有可显示的内容', 'aksrt')) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
: '<div class="c-red muted-box mb20"><b>' . esc_html__('幻灯片模块:', 'aksrt') . '</b>' . esc_html__('当前配置下没有可显示的内容,请正确配置或移出该模块', 'aksrt') . '</div>';
|
||||
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$interval = max(0, min(20, (int) ($instance['interval'] ?? 4)));
|
||||
$loop = !isset($instance['loop']) || !empty($instance['loop']);
|
||||
$dots = !isset($instance['pagination']) || !empty($instance['pagination']);
|
||||
$nav = !isset($instance['button']) || !empty($instance['button']);
|
||||
$blank = !empty($instance['blank']);
|
||||
$height = max(80, min(800, (int) ($instance['height'] ?? $instance['pc_height'] ?? 400)));
|
||||
$m_height = max(60, min(800, (int) ($instance['m_height'] ?? $height)));
|
||||
$effect = sanitize_key((string) ($instance['effect'] ?? 'slide'));
|
||||
if (!in_array($effect, ['slide', 'fade', 'cube', 'coverflow', 'flip'], true)) {
|
||||
$effect = 'slide';
|
||||
}
|
||||
// Zibll CFS_Module::slide() options parity.
|
||||
$direction = sanitize_key((string) ($instance['direction'] ?? 'horizontal'));
|
||||
if (!in_array($direction, ['horizontal', 'vertical'], true)) {
|
||||
$direction = 'horizontal';
|
||||
}
|
||||
$autoplay = !isset($instance['autoplay']) || !empty($instance['autoplay']);
|
||||
$speed = max(0, min(3000, (int) ($instance['speed'] ?? 0)));
|
||||
$spacebetween= max(0, min(500, (int) ($instance['spacebetween'] ?? 15)));
|
||||
$scale_height= !empty($instance['scale_height']) || !isset($instance['scale_height']);
|
||||
$scale = max(10, min(300, (int) ($instance['scale'] ?? 35)));
|
||||
|
||||
$slide_payload = [];
|
||||
foreach ($slides as $slide) {
|
||||
$slide_payload[] = [
|
||||
'image' => $slide['image'],
|
||||
'link' => $slide['href'],
|
||||
'title' => $slide['title'],
|
||||
'desc' => $slide['desc'],
|
||||
'alt' => $slide['title'],
|
||||
'target' => $blank ? '_blank' : '_self',
|
||||
];
|
||||
}
|
||||
|
||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
$title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base);
|
||||
if ($title !== '') {
|
||||
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
if (function_exists('aksrt_render_slider')) {
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo aksrt_render_slider([
|
||||
'slides' => $slide_payload,
|
||||
'effect' => $effect,
|
||||
'loop' => $loop,
|
||||
'autoplay' => $autoplay,
|
||||
'interval' => $interval * 1000,
|
||||
'speed' => $speed,
|
||||
'direction' => $direction,
|
||||
'spaceBetween' => $spacebetween,
|
||||
'pc_height' => $height . 'px',
|
||||
'm_height' => $m_height . 'px',
|
||||
'scale_height' => $scale_height && $direction !== 'vertical',
|
||||
'scale_ratio' => $scale / 100,
|
||||
'show_nav' => $nav,
|
||||
'show_pagination' => $dots,
|
||||
'slider_class' => 'slide-widget',
|
||||
'wrapper_class' => 'aksrt-widget-slider-wrap',
|
||||
]);
|
||||
} else {
|
||||
// Minimal fallback without helper.
|
||||
echo '<div class="aksrt-widget-slider" style="--aksrt-slider-h:' . (int) $height . 'px">';
|
||||
foreach ($slide_payload as $i => $slide) {
|
||||
$active = $i === 0 ? ' is-active' : '';
|
||||
echo '<div class="aksrt-widget-slider__slide' . esc_attr($active) . '">';
|
||||
$img = '<img src="' . esc_url($slide['image']) . '" alt="' . esc_attr($slide['title']) . '" loading="lazy" />';
|
||||
if ($slide['link'] !== '') {
|
||||
echo '<a href="' . esc_url($slide['link']) . '"' . ($blank ? ' target="_blank" rel="noopener noreferrer"' : '') . '>' . $img . '</a>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
} else {
|
||||
echo $img; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
public function form($instance): void {
|
||||
$title = (string) ($instance['title'] ?? '');
|
||||
$interval = (int) ($instance['interval'] ?? 4);
|
||||
$height = (int) ($instance['height'] ?? $instance['pc_height'] ?? 400);
|
||||
$m_height = (int) ($instance['m_height'] ?? $height);
|
||||
$effect = sanitize_key((string) ($instance['effect'] ?? 'slide'));
|
||||
$direction = sanitize_key((string) ($instance['direction'] ?? 'horizontal'));
|
||||
$speed = (int) ($instance['speed'] ?? 0);
|
||||
$spacebetween = (int) ($instance['spacebetween'] ?? 15);
|
||||
$scale = (int) ($instance['scale'] ?? 35);
|
||||
$slides = $this->normalize_slides($instance['slides'] ?? []);
|
||||
if (!$slides) {
|
||||
$slides = [
|
||||
['image' => '', 'href' => '', 'title' => '', 'desc' => ''],
|
||||
['image' => '', 'href' => '', 'title' => '', 'desc' => ''],
|
||||
];
|
||||
}
|
||||
?>
|
||||
<p>
|
||||
<label><?php esc_html_e('标题', 'aksrt'); ?>
|
||||
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('title')); ?>" value="<?php echo esc_attr($title); ?>">
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php esc_html_e('幻灯片方向', 'aksrt'); ?>
|
||||
<select name="<?php echo esc_attr($this->get_field_name('direction')); ?>">
|
||||
<option value="horizontal" <?php selected($direction, 'horizontal'); ?>><?php esc_html_e('左右切换', 'aksrt'); ?></option>
|
||||
<option value="vertical" <?php selected($direction, 'vertical'); ?>><?php esc_html_e('上下切换', 'aksrt'); ?></option>
|
||||
</select>
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php esc_html_e('切换效果', 'aksrt'); ?>
|
||||
<select name="<?php echo esc_attr($this->get_field_name('effect')); ?>">
|
||||
<option value="slide" <?php selected($effect, 'slide'); ?>><?php esc_html_e('滑动', 'aksrt'); ?></option>
|
||||
<option value="fade" <?php selected($effect, 'fade'); ?>><?php esc_html_e('淡入', 'aksrt'); ?></option>
|
||||
<option value="coverflow" <?php selected($effect, 'coverflow'); ?>><?php esc_html_e('Coverflow', 'aksrt'); ?></option>
|
||||
<option value="cube" <?php selected($effect, 'cube'); ?>><?php esc_html_e('Cube', 'aksrt'); ?></option>
|
||||
<option value="flip" <?php selected($effect, 'flip'); ?>><?php esc_html_e('Flip', 'aksrt'); ?></option>
|
||||
</select>
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php esc_html_e('PC 高度(px)', 'aksrt'); ?>
|
||||
<input class="tiny-text" type="number" min="80" max="800" name="<?php echo esc_attr($this->get_field_name('height')); ?>" value="<?php echo esc_attr((string) $height); ?>">
|
||||
</label>
|
||||
<label><?php esc_html_e('移动端高度(px)', 'aksrt'); ?>
|
||||
<input class="tiny-text" type="number" min="60" max="800" name="<?php echo esc_attr($this->get_field_name('m_height')); ?>" value="<?php echo esc_attr((string) $m_height); ?>">
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('scale_height')); ?>" value="1" <?php checked(!isset($instance['scale_height']) || !empty($instance['scale_height'])); ?>> <?php esc_html_e('按比例自动高度', 'aksrt'); ?></label>
|
||||
<label><?php esc_html_e('长宽比例 %', 'aksrt'); ?>
|
||||
<input class="tiny-text" type="number" min="10" max="300" step="5" name="<?php echo esc_attr($this->get_field_name('scale')); ?>" value="<?php echo esc_attr((string) $scale); ?>">
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php esc_html_e('间距(px)', 'aksrt'); ?>
|
||||
<input class="tiny-text" type="number" min="0" max="500" step="5" name="<?php echo esc_attr($this->get_field_name('spacebetween')); ?>" value="<?php echo esc_attr((string) $spacebetween); ?>">
|
||||
</label>
|
||||
<label><?php esc_html_e('切换速度(ms,0=自动)', 'aksrt'); ?>
|
||||
<input class="tiny-text" type="number" min="0" max="3000" step="100" name="<?php echo esc_attr($this->get_field_name('speed')); ?>" value="<?php echo esc_attr((string) $speed); ?>">
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php esc_html_e('停顿时间(秒)', 'aksrt'); ?>
|
||||
<input class="tiny-text" type="number" min="0" max="20" name="<?php echo esc_attr($this->get_field_name('interval')); ?>" value="<?php echo esc_attr((string) $interval); ?>">
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('loop')); ?>" value="1" <?php checked(!empty($instance['loop']) || !isset($instance['loop'])); ?>> <?php esc_html_e('循环播放', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('button')); ?>" value="1" <?php checked(!empty($instance['button']) || !isset($instance['button'])); ?>> <?php esc_html_e('翻页按钮', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('pagination')); ?>" value="1" <?php checked(!empty($instance['pagination']) || !isset($instance['pagination'])); ?>> <?php esc_html_e('指示点', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('autoplay')); ?>" value="1" <?php checked(!isset($instance['autoplay']) || !empty($instance['autoplay'])); ?>> <?php esc_html_e('自动播放', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('blank')); ?>" value="1" <?php checked(!empty($instance['blank'])); ?>> <?php esc_html_e('新窗口打开', 'aksrt'); ?></label>
|
||||
</p>
|
||||
<?php foreach ($slides as $i => $slide) : ?>
|
||||
<p style="border-top:1px solid #ddd;padding-top:8px;">
|
||||
<strong><?php echo esc_html(sprintf(__('幻灯片 %d', 'aksrt'), $i + 1)); ?></strong><br>
|
||||
<label><?php esc_html_e('图片 URL', 'aksrt'); ?>
|
||||
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('slides') . "[{$i}][image]"); ?>" value="<?php echo esc_attr($slide['image']); ?>">
|
||||
</label>
|
||||
<label><?php esc_html_e('链接', 'aksrt'); ?>
|
||||
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('slides') . "[{$i}][href]"); ?>" value="<?php echo esc_attr($slide['href']); ?>">
|
||||
</label>
|
||||
<label><?php esc_html_e('标题', 'aksrt'); ?>
|
||||
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('slides') . "[{$i}][title]"); ?>" value="<?php echo esc_attr($slide['title']); ?>">
|
||||
</label>
|
||||
<label><?php esc_html_e('简介', 'aksrt'); ?>
|
||||
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('slides') . "[{$i}][desc]"); ?>" value="<?php echo esc_attr($slide['desc']); ?>">
|
||||
</label>
|
||||
</p>
|
||||
<?php endforeach; ?>
|
||||
<?php
|
||||
$extra = max(0, 4 - count($slides));
|
||||
for ($j = 0; $j < $extra; $j++) {
|
||||
$i = count($slides) + $j;
|
||||
?>
|
||||
<p style="border-top:1px dashed #eee;padding-top:8px;">
|
||||
<strong><?php echo esc_html(sprintf(__('空槽 %d', 'aksrt'), $i + 1)); ?></strong>
|
||||
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('slides') . "[{$i}][image]"); ?>" placeholder="<?php esc_attr_e('图片 URL', 'aksrt'); ?>">
|
||||
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('slides') . "[{$i}][href]"); ?>" placeholder="<?php esc_attr_e('链接', 'aksrt'); ?>">
|
||||
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('slides') . "[{$i}][title]"); ?>" placeholder="<?php esc_attr_e('标题', 'aksrt'); ?>">
|
||||
<input class="widefat" type="text" name="<?php echo esc_attr($this->get_field_name('slides') . "[{$i}][desc]"); ?>" placeholder="<?php esc_attr_e('简介', 'aksrt'); ?>">
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<p class="description"><?php esc_html_e('使用主题共享 Swiper(.new-swiper)。图片 URL 必填;仅 1 张时不滑动。', 'aksrt'); ?></p>
|
||||
<p class="description"><?php esc_html_e('对齐 Zibll 幻灯片:方向/效果/比例自动高度/间距/速度/自动播放/间隔。视频背景与图层视差由共享 Swiper 栈支持。', 'aksrt'); ?></p>
|
||||
<?php
|
||||
$this->render_common_form_section($instance);
|
||||
}
|
||||
|
||||
public function update($new_instance, $old_instance): array {
|
||||
$slides = $this->normalize_slides($new_instance['slides'] ?? []);
|
||||
$effect = sanitize_key((string) ($new_instance['effect'] ?? 'slide'));
|
||||
if (!in_array($effect, ['slide', 'fade', 'cube', 'coverflow', 'flip'], true)) {
|
||||
$effect = 'slide';
|
||||
}
|
||||
$direction = sanitize_key((string) ($new_instance['direction'] ?? 'horizontal'));
|
||||
if (!in_array($direction, ['horizontal', 'vertical'], true)) {
|
||||
$direction = 'horizontal';
|
||||
}
|
||||
$business = [
|
||||
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
|
||||
'interval' => max(0, min(20, (int) ($new_instance['interval'] ?? 4))),
|
||||
'height' => max(80, min(800, (int) ($new_instance['height'] ?? $new_instance['pc_height'] ?? 400))),
|
||||
'm_height' => max(60, min(800, (int) ($new_instance['m_height'] ?? ($new_instance['height'] ?? $new_instance['pc_height'] ?? 400)))),
|
||||
'effect' => $effect,
|
||||
'direction' => $direction,
|
||||
'speed' => max(0, min(3000, (int) ($new_instance['speed'] ?? 0))),
|
||||
'spacebetween'=> max(0, min(500, (int) ($new_instance['spacebetween'] ?? 15))),
|
||||
'scale_height'=> !empty($new_instance['scale_height']) ? 1 : 0,
|
||||
'scale' => max(10, min(300, (int) ($new_instance['scale'] ?? 35))),
|
||||
'loop' => !empty($new_instance['loop']) ? 1 : 0,
|
||||
'button' => !empty($new_instance['button']) ? 1 : 0,
|
||||
'pagination' => !empty($new_instance['pagination']) ? 1 : 0,
|
||||
'autoplay' => !empty($new_instance['autoplay']) ? 1 : 0,
|
||||
'blank' => !empty($new_instance['blank']) ? 1 : 0,
|
||||
'slides' => $slides,
|
||||
]; return $this->update_common_fields($new_instance, $old_instance, $business);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $raw
|
||||
* @return array<int, array{image:string,href:string,title:string,desc:string}>
|
||||
*/
|
||||
private function normalize_slides($raw): array {
|
||||
if (!is_array($raw)) {
|
||||
return [];
|
||||
}
|
||||
$out = [];
|
||||
foreach ($raw as $row) {
|
||||
if (!is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
$image = esc_url_raw(trim((string) ($row['image'] ?? $row['link'] ?? '')));
|
||||
if ($image === '') {
|
||||
continue;
|
||||
}
|
||||
$out[] = [
|
||||
'image' => $image,
|
||||
'href' => esc_url_raw(trim((string) ($row['href'] ?? ''))),
|
||||
'title' => sanitize_text_field((string) ($row['title'] ?? '')),
|
||||
'desc' => sanitize_text_field((string) ($row['desc'] ?? $row['dec'] ?? '')),
|
||||
];
|
||||
if (count($out) >= 8) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user