*/ 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 (array_key_exists('paginate', $config) && in_array((string) $config['paginate'], ['', 'none'], true)) { $args['no_found_rows'] = true; $args['paged'] = 1; } // 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); $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) { $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')); $pay = $is_reference_segment ? '' : ($config['pay_type'] ?? ''); self::apply_pay_type($args, $pay); return $args; } /** @return list */ 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('AKSRT\\Core\\DomainModel') ? \AKSRT\Core\DomainModel::POST_VIEW_COUNT_KEY : 'aksrt_post_views', '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', ]; if (isset($meta[$orderby])) { $args['meta_key'] = $meta[$orderby]; $args['orderby'] = 'meta_value_num'; return; } if ($orderby === 'comments' || $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('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'; $pay_query = [ 'relation' => 'OR', ['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]; } }