Files
wordpress-theme-aksrt/src/WidgetSystem/PostQuery.php
T

136 lines
5.3 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
namespace Jio\WidgetSystem;
defined('ABSPATH') || exit;
/**
* Builds post queries exclusively from normalized, saved widget settings.
*/
final class PostQuery {
public static function build(array $instance, int $page = 1, array $segment = []): \WP_Query {
return new \WP_Query(self::arguments($instance, $page, $segment));
}
/** @return array<string,mixed> */
public static function arguments(array $instance, int $page = 1, array $segment = []): array {
$config = array_merge($instance, $segment);
$count = max(1, min(50, (int) ($config['count'] ?? 8)));
$args = [
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => $count,
'paged' => max(1, $page),
'ignore_sticky_posts' => true,
'no_found_rows' => false,
];
if (isset($config['paginate']) && $config['paginate'] === '') {
$args['no_found_rows'] = true;
$args['paged'] = 1;
}
// The modern post widgets use the 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);
if (array_key_exists('cat', $config)) {
// WP_Query's `cat` expands included parents to descendants and
// applies negative IDs as exclusions.
$categories = self::signed_ids((string) $config['cat']);
if ($categories) {
$args['cat'] = implode(',', $categories);
}
} else {
// Generic widgets retain their explicit category ID/list behavior.
$categories = self::signed_ids((string) ($config['category_ids'] ?? ''));
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 = RendererHelpers::ids((string) ($config['topics'] ?? ''));
if ($topics) {
$args['tax_query'] = [[
'taxonomy' => 'topics',
'field' => 'term_id',
'terms' => $topics,
]];
}
$days = max(0, (int) ($config['limit_day'] ?? 0));
if ($days > 0) {
$now = current_datetime();
$args['date_query'] = [[
'after' => $now->modify('-' . $days . ' days')->format('Y-m-d H:i:s'),
'before' => $now->format('Y-m-d H:i:s'),
'inclusive' => true,
]];
}
self::apply_order($args, (string) ($config['orderby'] ?? 'date'), (string) ($config['order'] ?? 'DESC'));
self::apply_pay_type($args, $config['pay_type'] ?? '');
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) {
return [];
}
$index = ctype_digit($segment) ? (int) $segment : 0;
return isset($tabs[$index]) && is_array($tabs[$index]) ? $tabs[$index] : $tabs[0];
}
private static function apply_order(array &$args, string $orderby, string $order): void {
$args['order'] = strtoupper($order) === 'ASC' ? 'ASC' : 'DESC';
$meta = [
'views' => class_exists('Jio\\Core\\DomainModel') ? \Jio\Core\DomainModel::POST_VIEW_COUNT_KEY : 'jio_post_views',
'like' => '_jio_like_count',
'favorite' => '_jio_favorite_count',
];
if (isset($meta[$orderby])) {
$args['meta_key'] = $meta[$orderby];
$args['orderby'] = 'meta_value_num';
return;
}
if ($orderby === 'comment_count') {
$args['orderby'] = 'comment_count';
} elseif (in_array($orderby, ['date', 'modified', 'rand'], true)) {
$args['orderby'] = $orderby;
} else {
$args['orderby'] = 'date';
}
}
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('Jio\\Core\\DomainModel') ? \Jio\Core\DomainModel::PAY_TYPE_KEY : '_jio_pay_type';
$meta_key = class_exists('Jio\\Core\\DomainModel') ? \Jio\Core\DomainModel::PAY_META_KEY : '_jio_pay';
$pay_query = [
'relation' => 'OR',
['key' => $type_key, 'value' => $values, 'compare' => 'IN'],
];
// Some Jio 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];
}
}