Files
wordpress-theme-aksrt/src/AKSRT/Widgets/WidgetForumTopicLists.php
T
kate522 d8682ce1fe feat(widgets): pricing/FAQ/stats + forum topic list and bbs sidebars
Add zibll produck widgets (pricing plans, FAQ, stats), forum topic
lists, register bbs_* sidebar zones, and wire plate/topic/home/compose
templates to render those widget areas.
2026-07-19 00:22:31 +08:00

177 lines
6.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Forum topic list widget (zibll zib_bbs_widget_ui_posts_lists lite).
*
* @package AKSRT
*/
namespace AKSRT\Widgets;
defined('ABSPATH') || exit;
class WidgetForumTopicLists extends \WP_Widget {
public function __construct() {
parent::__construct(
'aksrt_forum_topic_lists',
esc_html__('论坛 - 帖子列表', 'aksrt'),
[
'description' => esc_html__('按排序/版块筛选展示论坛帖子。', 'aksrt'),
'classname' => 'widget_aksrt_forum_topic_lists',
]
);
}
public function widget($args, $instance): void {
if (!post_type_exists('aksrt_forum_topic')) {
return;
}
$count = max(1, min(30, (int) ($instance['count'] ?? 8)));
$orderby = sanitize_key((string) ($instance['orderby'] ?? 'date'));
$style = sanitize_key((string) ($instance['style'] ?? 'mini'));
$plate_id = (int) ($instance['plate_id'] ?? 0);
$current_plate = !empty($instance['current_plate']);
if ($current_plate) {
$resolved = $this->resolve_current_plate_id();
if ($resolved <= 0) {
return;
}
$plate_id = $resolved;
}
$query = [
'post_type' => 'aksrt_forum_topic',
'post_status' => 'publish',
'posts_per_page' => $count,
'order' => 'DESC',
];
switch ($orderby) {
case 'views':
$query['meta_key'] = '_aksrt_views';
$query['orderby'] = 'meta_value_num';
break;
case 'comments':
$query['orderby'] = 'comment_count';
break;
case 'modified':
$query['orderby'] = 'modified';
break;
default:
$query['orderby'] = 'date';
}
if ($plate_id > 0) {
$query['meta_query'] = [[
'key' => '_aksrt_plate_id',
'value' => $plate_id,
]];
}
$q = new \WP_Query($query);
if (!$q->have_posts()) {
wp_reset_postdata();
return;
}
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
}
$list_class = $style === 'detail' ? 'aksrt-ftopic-list is-detail' : 'aksrt-ftopic-list is-mini';
echo '<ul class="' . esc_attr($list_class) . '">';
while ($q->have_posts()) {
$q->the_post();
$views = (int) get_post_meta(get_the_ID(), '_aksrt_views', true);
echo '<li class="aksrt-ftopic-list__item">';
echo '<a class="aksrt-ftopic-list__link" href="' . esc_url(get_permalink()) . '">' . esc_html(get_the_title()) . '</a>';
if ($style === 'detail') {
echo '<div class="aksrt-ftopic-list__meta">';
echo '<span>' . esc_html(get_the_author()) . '</span>';
echo '<span>' . esc_html(get_the_date()) . '</span>';
echo '<span><i class="fas fa-eye"></i> ' . esc_html((string) $views) . '</span>';
echo '</div>';
} else {
echo '<span class="aksrt-ftopic-list__views">' . esc_html((string) $views) . '</span>';
}
echo '</li>';
}
echo '</ul>';
wp_reset_postdata();
echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
private function resolve_current_plate_id(): int {
if (is_singular('aksrt_forum_plate')) {
return (int) get_queried_object_id();
}
if (is_singular('aksrt_forum_topic')) {
$topic_id = (int) get_queried_object_id();
$plate_id = (int) get_post_meta($topic_id, '_aksrt_plate_id', true);
return max(0, $plate_id);
}
return 0;
}
public function form($instance): void {
?>
<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((string) ($instance['title'] ?? __('最新帖子', 'aksrt'))); ?>">
</label>
</p>
<p>
<label><?php esc_html_e('数量', 'aksrt'); ?>
<input class="tiny-text" type="number" min="1" max="30" name="<?php echo esc_attr($this->get_field_name('count')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['count'] ?? 8))); ?>">
</label>
</p>
<p>
<label><?php esc_html_e('排序', 'aksrt'); ?>
<select name="<?php echo esc_attr($this->get_field_name('orderby')); ?>">
<option value="date" <?php selected(($instance['orderby'] ?? 'date'), 'date'); ?>><?php esc_html_e('发布时间', 'aksrt'); ?></option>
<option value="views" <?php selected(($instance['orderby'] ?? ''), 'views'); ?>><?php esc_html_e('浏览量', 'aksrt'); ?></option>
<option value="comments" <?php selected(($instance['orderby'] ?? ''), 'comments'); ?>><?php esc_html_e('评论数', 'aksrt'); ?></option>
<option value="modified" <?php selected(($instance['orderby'] ?? ''), 'modified'); ?>><?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('style')); ?>">
<option value="mini" <?php selected(($instance['style'] ?? 'mini'), 'mini'); ?>><?php esc_html_e('紧凑', 'aksrt'); ?></option>
<option value="detail" <?php selected(($instance['style'] ?? ''), 'detail'); ?>><?php esc_html_e('详情', 'aksrt'); ?></option>
</select>
</label>
</p>
<p>
<label><?php esc_html_e('限定版块 ID(0=全部)', 'aksrt'); ?>
<input class="tiny-text" type="number" min="0" name="<?php echo esc_attr($this->get_field_name('plate_id')); ?>" value="<?php echo esc_attr((string) ((int) ($instance['plate_id'] ?? 0))); ?>">
</label>
</p>
<p>
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('current_plate')); ?>" value="1" <?php checked(!empty($instance['current_plate'])); ?>> <?php esc_html_e('仅当前版块(版块/帖子页)', 'aksrt'); ?></label>
</p>
<?php
}
public function update($new_instance, $old_instance): array {
$orderby = sanitize_key((string) ($new_instance['orderby'] ?? 'date'));
if (!in_array($orderby, ['date', 'views', 'comments', 'modified'], true)) {
$orderby = 'date';
}
return [
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
'count' => max(1, min(30, (int) ($new_instance['count'] ?? 8))),
'orderby' => $orderby,
'style' => ($new_instance['style'] ?? '') === 'detail' ? 'detail' : 'mini',
'plate_id' => max(0, (int) ($new_instance['plate_id'] ?? 0)),
'current_plate' => !empty($new_instance['current_plate']) ? 1 : 0,
];
}
}