Files
wordpress-theme-aksrt/src/AKSRT/Widgets/CategoryTabsWidget.php
T
kate522 3cf0c08969 fix(autoload): one PSR-4 type per payment/widget file
PSR-4 split left GatewayInterface/Gateway duplicated across files;
loading BalanceGateway redeclared the interface. Strip sibling types
from polluted files (payment + widgets) so each path owns one type.
2026-07-17 14:44:36 +08:00

188 lines
7.8 KiB
PHP

<?php
/**
* @package AKSRT
*/
namespace AKSRT\Widgets;
defined('ABSPATH') || exit;
/**
* Homepage category tabs widget.
*/
class CategoryTabsWidget extends \WP_Widget {
public function __construct() {
parent::__construct(
'aksrt_category_tabs',
esc_html__('AKSRT 分类 Tabs', 'aksrt'),
[
'classname' => 'widget_aksrt_category_tabs',
'description' => esc_html__('多分类切换内容流,可挂载到首页内容挂载区。', 'aksrt'),
'customize_selective_refresh' => true,
]
);
}
public function widget($args, $instance): void {
$context = aksrt_home_widget_resolve_context($args);
$title = apply_filters('widget_title', $instance['title'] ?? '', $instance, $this->id_base);
$title = $title !== '' ? $title : __('热门分类', 'aksrt');
$count = max(1, min(12, (int) ($instance['count'] ?? 6)));
$columns = aksrt_home_widget_effective_columns((int) ($instance['columns'] ?? 3), $context);
$layout = aksrt_home_widget_effective_layout(
aksrt_home_widget_resolve_layout($instance['layout'] ?? 'card', 'card'),
$context
);
$show_more = ! empty($instance['show_more']);
$tabs = $this->resolve_tabs($instance);
echo $args['before_widget'];
echo '<section class="aksrt-home-widget aksrt-home-widget--tabs widget-tab-posts">';
if (empty($tabs)) {
echo function_exists('aksrt_get_widget_null') ? aksrt_get_widget_null(__('暂无可用分类', 'aksrt')) : '<p class="widget-empty">' . esc_html__('暂无可用分类', 'aksrt') . '</p>';
echo '</section>';
echo $args['after_widget'];
return;
}
?>
<header class="aksrt-home-widget__header aksrt-home-widget__header--tabs">
<h3 class="aksrt-home-widget__title"><?php echo esc_html($title); ?></h3>
<ul class="widget-tab-posts__nav aksrt-home-widget__tab-nav" role="tablist">
<?php foreach ($tabs as $index => $tab) : ?>
<li role="presentation">
<button
type="button"
role="tab"
class="widget-tab-posts__tab<?php echo 0 === $index ? ' active' : ''; ?>"
data-tab="cat-<?php echo (int) $tab['id']; ?>"
aria-selected="<?php echo 0 === $index ? 'true' : 'false'; ?>"
>
<?php echo esc_html($tab['name']); ?>
</button>
</li>
<?php endforeach; ?>
</ul>
</header>
<?php
foreach ($tabs as $index => $tab) {
$query = new \WP_Query([
'post_type' => aksrt_home_widget_post_types(),
'post_status' => 'publish',
'posts_per_page' => $count,
'ignore_sticky_posts' => true,
'no_found_rows' => true,
'cat' => (int) $tab['id'],
]);
?>
<div class="widget-tab-posts__panel<?php echo 0 === $index ? ' active' : ''; ?>" data-tab-panel="cat-<?php echo (int) $tab['id']; ?>" role="tabpanel"<?php echo 0 === $index ? '' : ' hidden'; ?>>
<?php aksrt_home_widget_render_post_grid($query, $layout, $columns, $context); ?>
<?php if ($show_more) : ?>
<div class="aksrt-home-widget__footer">
<a class="aksrt-home-widget__more" href="<?php echo esc_url($tab['link']); ?>">
<?php esc_html_e('查看更多', 'aksrt'); ?>
</a>
</div>
<?php endif; ?>
</div>
<?php
}
echo '</section>';
echo $args['after_widget'];
}
public function form($instance): void {
$title = (string) ($instance['title'] ?? '');
$category_ids = aksrt_home_widget_normalize_category_ids($instance['category_ids'] ?? [], 6);
$count = (int) ($instance['count'] ?? 6);
$columns = (int) ($instance['columns'] ?? 3);
$layout = aksrt_home_widget_resolve_layout($instance['layout'] ?? 'card', 'card');
$show_more = ! empty($instance['show_more']);
$categories = aksrt_home_widget_available_categories();
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php esc_html_e('标题:', 'aksrt'); ?></label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr($title); ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('category_ids')); ?>"><?php esc_html_e('分类(可多选):', 'aksrt'); ?></label>
<select class="widefat" id="<?php echo esc_attr($this->get_field_id('category_ids')); ?>" name="<?php echo esc_attr($this->get_field_name('category_ids')); ?>[]" multiple size="6">
<?php foreach ($categories as $category) : ?>
<option value="<?php echo (int) $category->term_id; ?>" <?php selected(in_array((int) $category->term_id, $category_ids, true)); ?>>
<?php echo esc_html($category->name); ?>
</option>
<?php endforeach; ?>
</select>
<small><?php esc_html_e('留空时自动选择热门分类。', 'aksrt'); ?></small>
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('count')); ?>"><?php esc_html_e('每个 Tab 的文章数量:', 'aksrt'); ?></label>
<input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('count')); ?>" name="<?php echo esc_attr($this->get_field_name('count')); ?>" type="number" min="1" max="12" value="<?php echo (int) $count; ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('columns')); ?>"><?php esc_html_e('桌面列数:', 'aksrt'); ?></label>
<input class="tiny-text" id="<?php echo esc_attr($this->get_field_id('columns')); ?>" name="<?php echo esc_attr($this->get_field_name('columns')); ?>" type="number" min="1" max="4" value="<?php echo (int) $columns; ?>">
</p>
<p>
<label for="<?php echo esc_attr($this->get_field_id('layout')); ?>"><?php esc_html_e('布局:', 'aksrt'); ?></label>
<select class="widefat" id="<?php echo esc_attr($this->get_field_id('layout')); ?>" name="<?php echo esc_attr($this->get_field_name('layout')); ?>">
<?php foreach (aksrt_home_widget_allowed_layouts() as $value => $label) : ?>
<option value="<?php echo esc_attr($value); ?>" <?php selected($layout, $value); ?>>
<?php echo esc_html($label); ?>
</option>
<?php endforeach; ?>
</select>
</p>
<p>
<input class="checkbox" type="checkbox" <?php checked($show_more); ?> id="<?php echo esc_attr($this->get_field_id('show_more')); ?>" name="<?php echo esc_attr($this->get_field_name('show_more')); ?>" value="1">
<label for="<?php echo esc_attr($this->get_field_id('show_more')); ?>"><?php esc_html_e('显示“查看更多”链接', 'aksrt'); ?></label>
</p>
<?php if (function_exists('aksrt_widget_render_location_help')) { aksrt_widget_render_location_help('hybrid'); } ?>
<?php
}
public function update($new_instance, $old_instance): array {
return [
'title' => sanitize_text_field($new_instance['title'] ?? ''),
'category_ids' => aksrt_home_widget_normalize_category_ids($new_instance['category_ids'] ?? [], 6),
'count' => max(1, min(12, absint($new_instance['count'] ?? 6))),
'columns' => max(1, min(4, absint($new_instance['columns'] ?? 3))),
'layout' => aksrt_home_widget_resolve_layout($new_instance['layout'] ?? 'card', 'card'),
'show_more' => ! empty($new_instance['show_more']) ? 1 : 0,
];
}
/**
* Resolve configured category tabs.
*
* @param array $instance Widget instance.
* @return array<int, array{id:int,name:string,link:string}>
*/
private function resolve_tabs(array $instance): array {
$category_ids = aksrt_home_widget_normalize_category_ids($instance['category_ids'] ?? [], 6);
if (empty($category_ids)) {
$category_ids = aksrt_home_widget_fallback_category_ids(4);
}
$tabs = [];
foreach ($category_ids as $category_id) {
$term = get_term($category_id, 'category');
if (! $term || is_wp_error($term)) {
continue;
}
$tabs[] = [
'id' => (int) $category_id,
'name' => $term->name,
'link' => get_category_link($category_id),
];
}
return $tabs;
}
}