Files
wordpress-theme-aksrt/inc/classes/settings/class-aksrt-settings-category-runtime.php
T

187 lines
6.1 KiB
PHP

<?php
/**
* Settings category recommend runtime helper.
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
class AKSRT_Settings_Category_Runtime {
/**
* 获取分类推荐配置(含默认值)
* @return array
*/
public static function get_category_recommend_settings(): array {
$defaults = [
'enable_category_recommend' => 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;
}
}