false, 'category_recommend_title' => __('分类推荐', 'aksrt'), 'category_recommend_category_ids' => [], 'category_recommend_posts_per_category' => 5, 'category_recommend_columns' => 2, 'category_recommend_show_description' => true, 'category_recommend_show_dates' => true, 'category_recommend_show_more_link' => true, ]; $saved = get_option('aksrt_category_recommend', []); return array_merge($defaults, $saved); } /** * 获取分类封面图 URL(带优先级回退) * * 优先级: * 1. aksrt_category_cover_id term meta * 2. 该分类最新一篇有缩略图文章的缩略图 * 3. 默认占位图 * * @param int $term_id * @return string */ public static function get_category_cover_url(int $term_id): string { $cover_id = (int) get_term_meta($term_id, 'aksrt_category_cover_id', true); if ($cover_id > 0) { $url = wp_get_attachment_url($cover_id); if ($url) { return $url; } } $posts = get_posts([ 'category__in' => [$term_id], 'posts_per_page' => 1, 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC', 'meta_query' => [ [ 'key' => '_thumbnail_id', 'compare' => 'EXISTS', ], ], 'fields' => 'ids', ]); if (!empty($posts)) { $thumb_url = get_the_post_thumbnail_url($posts[0], 'medium_large'); if ($thumb_url) { return $thumb_url; } } return get_template_directory_uri() . '/assets/img/placeholder.svg'; } /** * 获取分类推荐描述(带优先级回退) * * 优先级: * 1. aksrt_category_recommend_desc term meta * 2. 原生 category description * 3. 空字符串 * * @param int $term_id * @return string */ public static function get_category_recommend_desc(int $term_id): string { $description = (string) get_term_meta($term_id, 'aksrt_category_recommend_desc', true); if ($description !== '') { return $description; } $term = get_term($term_id, 'category'); if ($term && !is_wp_error($term) && $term->description) { return $term->description; } return ''; } /** * 清理分类推荐缓存 */ public static function flush_category_recommend_cache(): void { $keys = get_option('aksrt_category_recommend_cache_keys', []); if (is_array($keys)) { foreach ($keys as $key) { delete_transient($key); } } delete_option('aksrt_category_recommend_cache_keys'); } /** * 获取分类推荐渲染数据(带缓存) * * @param array $settings 分类推荐配置 * @return array 每项包含 term_id, name, description, count, link, cover, posts */ public static function get_category_recommend_items(array $settings): array { $category_ids = array_map('absint', (array) ($settings['category_recommend_category_ids'] ?? [])); $category_ids = array_filter($category_ids, fn($id) => $id > 0); if (empty($category_ids)) { return []; } $per_page = max(1, min(10, (int) ($settings['category_recommend_posts_per_category'] ?? 5))); $show_desc = !empty($settings['category_recommend_show_description']); $show_dates = !empty($settings['category_recommend_show_dates']); $show_more = !empty($settings['category_recommend_show_more_link']); $cache_key = 'aksrt_cr_' . md5(implode(',', $category_ids) . '|' . $per_page . '|' . (int) $show_desc . '|' . (int) $show_dates . '|' . (int) $show_more); $cached = get_transient($cache_key); if ($cached !== false) { return $cached; } $items = []; foreach ($category_ids as $term_id) { $term = get_term($term_id, 'category'); if (!$term || is_wp_error($term)) { continue; } $description = $show_desc ? self::get_category_recommend_desc($term_id) : ''; $recent_posts = get_posts([ 'category__in' => [$term_id], 'posts_per_page' => $per_page, 'post_status' => 'publish', 'orderby' => 'date', 'order' => 'DESC', ]); $posts = []; foreach ($recent_posts as $post) { $posts[] = [ 'title' => get_the_title($post->ID), 'link' => get_permalink($post->ID), 'date' => get_the_date('Y-m-d', $post->ID), ]; } $items[] = [ 'term_id' => (int) $term_id, 'name' => $term->name, 'description' => $description, 'count' => (int) $term->count, 'link' => get_category_link($term_id), 'cover' => self::get_category_cover_url($term_id), 'posts' => $posts, ]; } set_transient($cache_key, $items, 12 * HOUR_IN_SECONDS); $keys = get_option('aksrt_category_recommend_cache_keys', []); if (!is_array($keys)) { $keys = []; } $keys[] = $cache_key; update_option('aksrt_category_recommend_cache_keys', array_unique($keys)); return $items; } }