对小工具进行了一些修复

This commit is contained in:
2026-08-26 08:41:24 +08:00
parent e877ceb560
commit bb9413cba6
15 changed files with 463 additions and 136 deletions
+62 -23
View File
@@ -8,8 +8,6 @@ defined('ABSPATH') || exit;
* Builds post queries exclusively from normalized, saved widget settings.
*/
final class PostQuery {
private const PAY_TYPES = ['reading', 'download', 'gallery', 'video', 'vip'];
public static function build(array $instance, int $page = 1, array $segment = []): \WP_Query {
return new \WP_Query(self::arguments($instance, $page, $segment));
}
@@ -26,28 +24,60 @@ final class PostQuery {
'ignore_sticky_posts' => true,
'no_found_rows' => false,
];
if (array_key_exists('paginate', $config) && in_array((string) $config['paginate'], ['', 'none'], true)) {
$args['no_found_rows'] = true;
$args['paged'] = 1;
}
$categories = RendererHelpers::ids((string) ($config['category_ids'] ?? ''));
if (!empty($config['category_id'])) {
$categories = [(int) $config['category_id']];
}
if ($categories) {
$args['category__in'] = $categories;
}
$tags = RendererHelpers::ids((string) ($config['tag_ids'] ?? ''));
// 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);
$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']];
$cat_in = array_values(array_filter($categories, static fn(int $id): bool => $id > 0));
$cat_not = array_values(array_map('abs', array_filter($categories, static fn(int $id): bool => $id < 0)));
if ($cat_in) $args['category__in'] = $cat_in;
if ($cat_not) $args['category__not_in'] = $cat_not;
$tags = $is_reference_segment ? [] : RendererHelpers::ids((string) ($config['tag_ids'] ?? ''));
if ($tags) {
$args['tag__in'] = $tags;
}
$topics_raw = (string) ($config['topics'] ?? '');
$topics = self::signed_ids($topics_raw);
if ($topics) {
$tax_query = [];
$topic_in = array_values(array_filter($topics, static fn(int $id): bool => $id > 0));
$topic_not = array_values(array_map('abs', array_filter($topics, static fn(int $id): bool => $id < 0)));
if ($topic_in) $tax_query[] = ['taxonomy' => 'topics', 'field' => 'term_id', 'terms' => $topic_in, 'include_children' => true];
if ($topic_not) $tax_query[] = ['taxonomy' => 'topics', 'field' => 'term_id', 'terms' => $topic_not, 'operator' => 'NOT IN', 'include_children' => true];
if (count($tax_query) > 1) $tax_query = array_merge(['relation' => 'AND'], $tax_query);
if ($tax_query) $args['tax_query'] = $tax_query;
}
$days = max(0, (int) ($config['limit_day'] ?? 0));
if ($days > 0) {
$args['date_query'] = [['after' => gmdate('Y-m-d', time() - ($days * DAY_IN_SECONDS)), 'inclusive' => true]];
$now = function_exists('current_time') ? current_time('timestamp') : time();
$format = static function (int $timestamp): string {
return function_exists('wp_date') ? wp_date('Y-m-d H:i:s', $timestamp) : date('Y-m-d H:i:s', $timestamp);
};
$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'));
self::apply_pay_type($args, (string) ($config['pay_type'] ?? ''));
$pay = array_key_exists('zibpay_type', $config) ? $config['zibpay_type'] : ($is_reference_segment ? '' : ($config['pay_type'] ?? ''));
self::apply_pay_type($args, $pay);
return $args;
}
/** @return list<int> */
private static function signed_ids(string $raw): array {
$tokens = preg_split('/[,,\s]+/', trim($raw), -1, PREG_SPLIT_NO_EMPTY) ?: [];
$out = [];
foreach ($tokens as $token) if (preg_match('/^-?\d+$/', (string) $token)) $out[] = (int) $token;
return array_values(array_unique(array_filter($out, static fn(int $id): bool => $id !== 0)));
}
public static function segment(array $instance, string $segment): array {
$tabs = array_values((array) ($instance['tabs'] ?? []));
if (!$tabs) {
@@ -61,16 +91,19 @@ final class PostQuery {
$args['order'] = strtoupper($order) === 'ASC' ? 'ASC' : 'DESC';
$meta = [
'views' => class_exists('AKSRT\\Core\\DomainModel') ? \AKSRT\Core\DomainModel::POST_VIEW_COUNT_KEY : 'aksrt_post_views',
'likes' => '_aksrt_like_count',
'favorites' => '_aksrt_favorite_count',
'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];
$args['orderby'] = 'meta_value_num';
return;
}
if ($orderby === 'comments') {
if ($orderby === 'comments' || $orderby === 'comment_count') {
$args['orderby'] = 'comment_count';
} elseif (in_array($orderby, ['date', 'modified', 'rand'], true)) {
$args['orderby'] = $orderby;
@@ -79,16 +112,22 @@ final class PostQuery {
}
}
private static function apply_pay_type(array &$args, string $pay_type): void {
if (!in_array($pay_type, self::PAY_TYPES, true)) {
return;
}
private static function apply_pay_type(array &$args, $pay_type): void {
$values = is_array($pay_type) ? array_map('strval', $pay_type) : array_filter(array_map('trim', preg_split('/[,,\s]+/', (string) $pay_type) ?: []));
$map = ['1' => 'reading', '2' => 'download', '5' => 'gallery', '6' => 'video', 'reading' => 'reading', 'download' => 'download', 'gallery' => 'gallery', 'video' => 'video', 'vip' => 'vip'];
$values = array_values(array_unique(array_filter(array_map(static fn($value): string => $map[(string) $value] ?? '', $values))));
if (!$values) return;
$type_key = class_exists('AKSRT\\Core\\DomainModel') ? \AKSRT\Core\DomainModel::PAY_TYPE_KEY : '_aksrt_pay_type';
$meta_key = class_exists('AKSRT\\Core\\DomainModel') ? \AKSRT\Core\DomainModel::PAY_META_KEY : '_aksrt_pay';
$args['meta_query'] = [[
$pay_query = [
'relation' => 'OR',
['key' => $type_key, 'value' => $pay_type, 'compare' => '='],
['key' => $meta_key, 'value' => '"pay_type";s:' . strlen($pay_type) . ':"' . $pay_type . '"', 'compare' => 'LIKE'],
]];
['key' => $type_key, 'value' => $values, 'compare' => 'IN'],
];
// Some AKSRT installations only have the structured pay array. LIKE
// accepts one scalar per clause, so emit a clause for each allowed type.
foreach ($values as $value) {
$pay_query[] = ['key' => $meta_key, 'value' => '"' . $value . '"', 'compare' => 'LIKE'];
}
$args['meta_query'] = [$pay_query];
}
}