对小工具进行了一些修复
This commit is contained in:
@@ -9,12 +9,10 @@ defined('ABSPATH') || exit;
|
||||
*/
|
||||
final class AdminFormController {
|
||||
public const AJAX_ACTION = 'aksrt_widget_form';
|
||||
public const SEARCH_ACTION = 'aksrt_widget_remote_options';
|
||||
private const NONCE_ACTION = 'aksrt_widget_form';
|
||||
|
||||
public static function register_hooks(): void {
|
||||
add_action('wp_ajax_' . self::AJAX_ACTION, [self::class, 'ajax_form']);
|
||||
add_action('wp_ajax_' . self::SEARCH_ACTION, [self::class, 'ajax_remote_options']);
|
||||
add_action('admin_enqueue_scripts', [self::class, 'enqueue']);
|
||||
add_action('customize_controls_enqueue_scripts', [self::class, 'enqueue']);
|
||||
}
|
||||
@@ -35,7 +33,6 @@ final class AdminFormController {
|
||||
wp_localize_script('aksrt-widget-admin', 'aksrtWidgetAdmin', [
|
||||
'ajaxUrl' => admin_url('admin-ajax.php'),
|
||||
'action' => self::AJAX_ACTION,
|
||||
'searchAction' => self::SEARCH_ACTION,
|
||||
'nonce' => wp_create_nonce(self::NONCE_ACTION),
|
||||
'transferNonce' => wp_create_nonce('aksrt_widgets_transfer'),
|
||||
'i18n' => [
|
||||
@@ -67,39 +64,5 @@ final class AdminFormController {
|
||||
$html = (string) ob_get_clean();
|
||||
wp_send_json_success(['html' => $html]);
|
||||
}
|
||||
|
||||
public static function ajax_remote_options(): void {
|
||||
check_ajax_referer(self::NONCE_ACTION, 'nonce');
|
||||
if (!current_user_can('edit_theme_options')) {
|
||||
wp_send_json_error(['message' => __('权限不足。', 'aksrt')], 403);
|
||||
}
|
||||
|
||||
$source = isset($_POST['source']) ? sanitize_key(wp_unslash($_POST['source'])) : '';
|
||||
$search = isset($_POST['search']) ? sanitize_text_field(wp_unslash($_POST['search'])) : '';
|
||||
$query_json = isset($_POST['queryArgs']) ? wp_unslash($_POST['queryArgs']) : '';
|
||||
$query_args = is_string($query_json) ? json_decode($query_json, true) : [];
|
||||
$query_args = is_array($query_args) ? $query_args : [];
|
||||
$results = [];
|
||||
|
||||
if ($source === 'post' && sanitize_key((string) ($query_args['post_type'] ?? '')) === 'plate') {
|
||||
$posts = get_posts([
|
||||
'post_type' => 'plate',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => 20,
|
||||
's' => $search,
|
||||
'orderby' => 'relevance date',
|
||||
'order' => 'DESC',
|
||||
]);
|
||||
foreach ($posts as $post) $results[] = ['id' => (string) $post->ID, 'text' => get_the_title($post) ?: '#' . $post->ID];
|
||||
} elseif ($source === 'categories') {
|
||||
$taxonomy = sanitize_key((string) ($query_args['taxonomy'] ?? ''));
|
||||
if (in_array($taxonomy, ['forum_topic', 'forum_tag'], true) && taxonomy_exists($taxonomy)) {
|
||||
$terms = get_terms(['taxonomy' => $taxonomy, 'hide_empty' => false, 'number' => 20, 'search' => $search]);
|
||||
if (!is_wp_error($terms)) foreach ($terms as $term) $results[] = ['id' => (string) $term->term_id, 'text' => (string) $term->name];
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_success(['results' => $results]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,21 +125,7 @@ final class FieldSchema {
|
||||
}
|
||||
|
||||
private static function choice(array $field, $value) {
|
||||
$raw_options = $field['options'] ?? [];
|
||||
// Reference-theme AJAX selects declare an option source (for example
|
||||
// `post` or `categories`) instead of an inline option map. Preserve the
|
||||
// selected IDs until the remote picker resolves their labels.
|
||||
if (!is_array($raw_options)) {
|
||||
if (!empty($field['multiple'])) {
|
||||
$values = is_array($value) ? $value : preg_split('/[,,\s]+/', (string) $value, -1, PREG_SPLIT_NO_EMPTY);
|
||||
return array_values(array_unique(array_filter(array_map(static function ($item): string {
|
||||
$item = trim((string) $item);
|
||||
return preg_match('/^\d+$/', $item) ? (string) (int) $item : '';
|
||||
}, $values ?: []))));
|
||||
}
|
||||
return sanitize_text_field((string) $value);
|
||||
}
|
||||
$options = $raw_options;
|
||||
$options = (array) ($field['options'] ?? []);
|
||||
if (!empty($field['multiple'])) {
|
||||
$values = is_array($value) ? $value : [];
|
||||
return array_values(array_filter(array_map('strval', $values), static fn($item) => array_key_exists($item, $options)));
|
||||
|
||||
@@ -128,10 +128,6 @@ final class FormRenderer {
|
||||
|
||||
private static function select(string $id, string $name, array $field, $value): void {
|
||||
$multiple = !empty($field['multiple']);
|
||||
if (!is_array($field['options'] ?? [])) {
|
||||
self::remote_select($id, $name, $field, $value);
|
||||
return;
|
||||
}
|
||||
echo '<select class="widefat" id="' . esc_attr($id) . '" name="' . esc_attr($name) . ($multiple ? '[]' : '') . '"' . ($multiple ? ' multiple' : '') . '>';
|
||||
$values = $multiple ? array_map('strval', (array) $value) : [(string) $value];
|
||||
foreach ((array) ($field['options'] ?? []) as $key => $label) {
|
||||
@@ -140,37 +136,6 @@ final class FormRenderer {
|
||||
echo '</select>';
|
||||
}
|
||||
|
||||
private static function remote_select(string $id, string $name, array $field, $value): void {
|
||||
$values = array_values(array_unique(array_filter(array_map('absint', (array) $value))));
|
||||
$options = self::remote_selected_options($field, $values);
|
||||
$source = (string) ($field['options'] ?? '');
|
||||
$query_args = wp_json_encode((array) ($field['query_args'] ?? []));
|
||||
$min_length = max(0, (int) ($field['settings']['min_length'] ?? 0));
|
||||
$placeholder = (string) ($field['placeholder'] ?? __('输入关键词以搜索', 'aksrt'));
|
||||
echo '<select class="widefat aksrt-widget-remote-select" id="' . esc_attr($id) . '" name="' . esc_attr($name) . '[]" multiple data-option-source="' . esc_attr($source) . '" data-query-args="' . esc_attr((string) $query_args) . '" data-min-length="' . $min_length . '" data-placeholder="' . esc_attr($placeholder) . '">';
|
||||
foreach ($options as $option_id => $label) {
|
||||
echo '<option value="' . esc_attr((string) $option_id) . '" selected>' . esc_html($label) . '</option>';
|
||||
}
|
||||
echo '</select>';
|
||||
}
|
||||
|
||||
private static function remote_selected_options(array $field, array $values): array {
|
||||
$options = [];
|
||||
$source = (string) ($field['options'] ?? '');
|
||||
$query_args = (array) ($field['query_args'] ?? []);
|
||||
foreach ($values as $value) {
|
||||
$label = '';
|
||||
if ($source === 'post' && function_exists('get_the_title')) {
|
||||
$label = (string) get_the_title($value);
|
||||
} elseif ($source === 'categories' && function_exists('get_term')) {
|
||||
$term = get_term($value, sanitize_key((string) ($query_args['taxonomy'] ?? '')));
|
||||
if ($term && !is_wp_error($term)) $label = (string) $term->name;
|
||||
}
|
||||
$options[$value] = $label !== '' ? $label : '#' . $value;
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
private static function checkboxes(string $id, string $name, array $field, $value): void {
|
||||
$options = (array) ($field['options'] ?? []);
|
||||
if (!$options) {
|
||||
|
||||
@@ -32,7 +32,7 @@ final class PostQuery {
|
||||
// The modern tab widget uses Zibll's signed `cat` syntax. Legacy
|
||||
// category_ids remains available only to the unrelated generic posts
|
||||
// widgets; a tab segment must never fall back to it.
|
||||
$is_reference_segment = array_key_exists('cat', $segment) || array_key_exists('topics', $segment) || array_key_exists('zibpay_type', $segment);
|
||||
$is_reference_segment = array_key_exists('cat', $segment) || array_key_exists('topics', $segment);
|
||||
$cat_raw = array_key_exists('cat', $config) ? (string) $config['cat'] : ($is_reference_segment ? '' : (string) ($config['category_ids'] ?? ''));
|
||||
$categories = self::signed_ids($cat_raw);
|
||||
if (!empty($config['category_id'])) $categories = [(int) $config['category_id']];
|
||||
@@ -65,7 +65,7 @@ final class PostQuery {
|
||||
$args['date_query'] = [['after' => $format($now - ($days * DAY_IN_SECONDS)), 'before' => $format($now), 'inclusive' => true]];
|
||||
}
|
||||
self::apply_order($args, (string) ($config['orderby'] ?? 'date'), (string) ($config['order'] ?? 'DESC'));
|
||||
$pay = array_key_exists('zibpay_type', $config) ? $config['zibpay_type'] : ($is_reference_segment ? '' : ($config['pay_type'] ?? ''));
|
||||
$pay = $is_reference_segment ? '' : ($config['pay_type'] ?? '');
|
||||
self::apply_pay_type($args, $pay);
|
||||
return $args;
|
||||
}
|
||||
@@ -94,9 +94,6 @@ final class PostQuery {
|
||||
'like' => '_aksrt_like_count', 'likes' => '_aksrt_like_count',
|
||||
'favorite' => '_aksrt_favorite_count', 'favorites' => '_aksrt_favorite_count',
|
||||
'downloads' => class_exists('AKSRT\\Core\\DomainModel') ? \AKSRT\Core\DomainModel::RESOURCE_DOWNLOAD_COUNT_KEY : '_aksrt_res_download_count',
|
||||
'zibpay_price' => class_exists('AKSRT\\Core\\DomainModel') ? \AKSRT\Core\DomainModel::PAY_PRICE_KEY : '_aksrt_pay_price',
|
||||
'zibpay_points_price' => '_aksrt_pay_points_price',
|
||||
'sales_volume' => class_exists('AKSRT\\Core\\DomainModel') ? \AKSRT\Core\DomainModel::RESOURCE_SALES_VOLUME_KEY : '_aksrt_sales_volume',
|
||||
];
|
||||
if (isset($meta[$orderby])) {
|
||||
$args['meta_key'] = $meta[$orderby];
|
||||
|
||||
@@ -260,29 +260,6 @@ final class GeneralRenderer {
|
||||
}
|
||||
wp_reset_postdata();
|
||||
}
|
||||
} elseif ($source === 'forums' && function_exists('zib_bbs_get_posts_query') && (!function_exists('_pz') || _pz('bbs_s'))) {
|
||||
$query_args = (array) ($i['forums_opts'] ?? []);
|
||||
$query_args['plate'] = $query_args['plate'] ?? 0;
|
||||
$query_args['paged_size'] = (int) ($i['count'] ?? 8);
|
||||
$query_args['paged'] = 1;
|
||||
$query_args['no_found_rows'] = true;
|
||||
$posts_query = zib_bbs_get_posts_query($query_args);
|
||||
$lists = [];
|
||||
if ($posts_query && method_exists($posts_query, 'have_posts')) {
|
||||
while ($posts_query->have_posts()) {
|
||||
$posts_query->the_post();
|
||||
$post_id = get_the_ID();
|
||||
$subtitle = class_exists('AKSRT\\Core\\PostMetaBox') ? \AKSRT\Core\PostMetaBox::get_meta_value($post_id, 'subtitle', '') : '';
|
||||
$title = trim(wp_strip_all_tags(get_the_title())) . trim(wp_strip_all_tags((string) $subtitle));
|
||||
if (!empty($i['desc_s'])) {
|
||||
$description = class_exists('AKSRT\\Core\\PostMetaBox') ? \AKSRT\Core\PostMetaBox::get_meta_value($post_id, 'description', '') : '';
|
||||
if (trim((string) $description) === '') $description = get_the_excerpt();
|
||||
$title .= ': ' . wp_html_excerpt(wp_strip_all_tags((string) $description), 160, '...');
|
||||
}
|
||||
$lists[] = ['title' => $title, 'href' => get_permalink()];
|
||||
}
|
||||
wp_reset_postdata();
|
||||
}
|
||||
}
|
||||
$msg_icon = ($posts_query && !empty($i['msg_icon'])) ? self::notice_icon((string) $i['msg_icon']) : '';
|
||||
$slides = '';
|
||||
|
||||
@@ -93,11 +93,10 @@ final class WidgetSchemas {
|
||||
['id' => 'radius', 'type' => 'switcher', 'label' => '两边显示为圆形', 'default' => false],
|
||||
['id' => 'interval', 'type' => 'spinner', 'label' => '滚动间隔', 'default' => 3, 'min' => 1, 'max' => 10, 'step' => 1, 'unit' => '秒'],
|
||||
['id' => 'color', 'type' => 'palette', 'label' => '颜色', 'default' => 'c-blue', 'options' => self::zib_palette()],
|
||||
['id' => 'source', 'type' => 'radio', 'label' => '内容来源', 'default' => '', 'options' => ['' => '自定义', 'posts' => '文章', 'forums' => '论坛帖子']],
|
||||
['id' => 'source', 'type' => 'radio', 'label' => '内容来源', 'default' => '', 'options' => ['' => '自定义', 'posts' => '文章']],
|
||||
['id' => 'msg_icon', 'type' => 'icon', 'label' => '消息图标', 'default' => 'zibsvg-hot', 'dependency' => ['source', '!=', '']],
|
||||
['id' => 'count', 'type' => 'spinner', 'label' => '获取帖子或文章数量', 'default' => 8, 'min' => 1, 'max' => 50, 'dependency' => ['source', '!=', '']],
|
||||
['id' => 'count', 'type' => 'spinner', 'label' => '获取文章数量', 'default' => 8, 'min' => 1, 'max' => 50, 'dependency' => ['source', '!=', '']],
|
||||
['id' => 'desc_s', 'type' => 'switcher', 'label' => '显示简介(关闭则只显示标题)', 'default' => false],
|
||||
['id' => 'forums_opts', 'type' => 'fieldset', 'label' => '论坛帖子筛选', 'default' => [], 'dependency' => ['source', '==', 'forums'], 'fields' => self::notice_forum_fields()],
|
||||
['id' => 'posts_opts', 'type' => 'fieldset', 'label' => '文章筛选', 'default' => [], 'dependency' => ['source', '==', 'posts'], 'fields' => self::notice_post_fields()],
|
||||
[
|
||||
'id' => 'img_ids', 'type' => 'group', 'label' => '消息列表', 'max_items' => 50,
|
||||
@@ -201,7 +200,6 @@ final class WidgetSchemas {
|
||||
['id' => 'title', 'type' => 'textarea', 'label' => '标题(必填)', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 1]],
|
||||
['id' => 'cat', 'type' => 'text', 'label' => '分类限制', 'default' => '', 'sanitize' => 'reference_ids'],
|
||||
['id' => 'topics', 'type' => 'text', 'label' => '专题限制', 'default' => '', 'sanitize' => 'reference_ids', 'description' => '多个 ID 用英文逗号隔开,支持负数排除。'],
|
||||
['id' => 'zibpay_type', 'type' => 'checkbox', 'label' => '商品类型筛选', 'default' => [], 'options' => ['1' => '付费阅读', '2' => '付费下载', '5' => '付费图片', '6' => '付费视频']],
|
||||
['id' => 'limit_day', 'type' => 'spinner', 'label' => '发布时间限制', 'default' => 0, 'min' => 0, 'step' => 5, 'max' => 3650],
|
||||
['id' => 'orderby', 'type' => 'select', 'label' => '排序方式', 'default' => '', 'options' => self::posts_orderby()],
|
||||
['id' => 'order', 'type' => 'radio', 'label' => '顺序', 'default' => 'desc', 'options' => ['desc' => '降序', 'asc' => '升序']],
|
||||
@@ -214,7 +212,7 @@ final class WidgetSchemas {
|
||||
return [
|
||||
'' => '默认排序', 'modified' => '更新时间', 'date' => '发布时间', 'views' => '浏览数量',
|
||||
'like' => '点赞数量', 'comment_count' => '评论数量', 'favorite' => '收藏数量',
|
||||
'zibpay_price' => '销售价格', 'zibpay_points_price' => '积分售价', 'sales_volume' => '销售数量', 'rand' => '随机排序',
|
||||
'rand' => '随机排序',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -468,35 +466,11 @@ final class WidgetSchemas {
|
||||
return [
|
||||
['id' => 'cat', 'type' => 'text', 'label' => '分类限制', 'default' => '', 'sanitize' => 'reference_ids'],
|
||||
['id' => 'topics', 'type' => 'text', 'label' => '专题限制', 'default' => '', 'sanitize' => 'reference_ids'],
|
||||
['id' => 'zibpay_type', 'type' => 'checkbox', 'label' => '商品类型筛选', 'default' => [], 'options' => ['1' => '付费阅读', '2' => '付费下载', '5' => '付费图片', '6' => '付费视频']],
|
||||
['id' => 'orderby', 'type' => 'select', 'label' => '排序方式', 'default' => '', 'options' => self::posts_orderby()],
|
||||
['id' => 'order', 'type' => 'radio', 'label' => '顺序', 'default' => 'desc', 'options' => ['desc' => '升序', 'asc' => '降序']],
|
||||
];
|
||||
}
|
||||
|
||||
private static function notice_forum_fields(): array {
|
||||
return [
|
||||
['id' => 'plate', 'type' => 'select', 'label' => '包含版块', 'default' => [], 'options' => 'post', 'query_args' => ['post_type' => 'plate'], 'ajax' => true, 'settings' => ['min_length' => 2], 'placeholder' => '输入关键词以搜索', 'chosen' => true, 'multiple' => true, 'sortable' => true],
|
||||
['id' => 'plate_exclude', 'type' => 'select', 'label' => '排除版块', 'default' => [], 'options' => 'post', 'query_args' => ['post_type' => 'plate'], 'ajax' => true, 'settings' => ['min_length' => 2], 'placeholder' => '输入关键词以搜索版块分类', 'chosen' => true, 'multiple' => true, 'sortable' => true, 'dependency' => ['plate', '==', '', '', 'visible']],
|
||||
['id' => 'topic', 'type' => 'select', 'label' => '包含话题', 'default' => [], 'options' => 'categories', 'query_args' => ['taxonomy' => 'forum_topic'], 'placeholder' => '输入关键词以搜索', 'chosen' => true, 'multiple' => true, 'sortable' => true, 'ajax' => true, 'settings' => ['min_length' => 2]],
|
||||
['id' => 'tag', 'type' => 'select', 'label' => '包含标签', 'default' => [], 'options' => 'categories', 'query_args' => ['taxonomy' => 'forum_tag'], 'placeholder' => '输入关键词以搜索', 'chosen' => true, 'multiple' => true, 'sortable' => true, 'ajax' => true, 'settings' => ['min_length' => 2]],
|
||||
['id' => 'bbs_type', 'type' => 'checkbox', 'label' => '类型筛选', 'default' => [], 'options' => ['' => '标准', 'question' => '提问']],
|
||||
['id' => 'allow_view', 'type' => 'checkbox', 'label' => '阅读权限筛选', 'default' => [], 'options' => ['signin' => '登录后查看', 'comment' => '评论后查看', 'pay' => '付费查看', 'points' => '支付积分查看', 'roles' => '部分用户可查看']],
|
||||
['id' => 'filter', 'type' => 'checkbox', 'label' => '其它筛选', 'default' => [], 'options' => ['topping' => '置顶帖子', 'vote' => '投票帖子', 'essence' => '精华帖子', 'question_status' => '提问已解决', 'is_hot' => '热门帖子']],
|
||||
['id' => 'orderby', 'type' => 'select', 'label' => '排序方式', 'default' => 'date', 'options' => self::notice_forum_orderby()],
|
||||
['id' => 'order', 'type' => 'radio', 'label' => '顺序', 'default' => 'desc', 'options' => ['desc' => '升序', 'asc' => '降序']],
|
||||
];
|
||||
}
|
||||
|
||||
private static function notice_forum_orderby(): array {
|
||||
return [
|
||||
'name' => '标题名称', 'date' => '最新发布', 'modified' => '最近更新', 'last_reply' => '最新回复',
|
||||
'dynamic_score' => '推荐指数', 'views' => '最多查看', 'score' => '评分最高', 'comment_count' => '最多回复',
|
||||
'favorite_count' => '最多收藏', 'zibpay_price' => '售价金额', 'zibpay_points_price' => '积分金额',
|
||||
'sales_volume' => '销售数量', 'rand' => '随机',
|
||||
];
|
||||
}
|
||||
|
||||
private static function pay_types(): array {
|
||||
return ['' => '全部', 'reading' => '付费阅读', 'download' => '付费下载', 'gallery' => '付费图库', 'video' => '付费视频', 'vip' => 'VIP 专属'];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user