187 lines
6.1 KiB
PHP
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;
|
|
}
|
|
}
|