diff --git a/inc/helpers/aksrt-widgets-markup.php b/inc/helpers/aksrt-widgets-markup.php index cd3f0cd0..0cdd1a0c 100644 --- a/inc/helpers/aksrt-widgets-markup.php +++ b/inc/helpers/aksrt-widgets-markup.php @@ -40,16 +40,36 @@ endif; if (!function_exists('aksrt_widget_term_cover_url')) : /** - * Category cover image URL with the theme meta fallback chain. + * Category cover image URL, resolved through the theme's canonical chain: + * explicit term cover → latest thumbnailed post inside the term → optional + * default placeholder. The reference hides term cards without a real cover + * while the aggregation card always falls back to a default image, so the + * last step is opt-in via $default_fallback. */ - function aksrt_widget_term_cover_url(int $term_id): string { - foreach (['aksrt_cover_url', 'cover_url'] as $meta_key) { - $url = esc_url_raw((string) get_term_meta($term_id, $meta_key, true)); + function aksrt_widget_term_cover_url(int $term_id, bool $default_fallback = false): 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; + return (string) $url; } } - return ''; + $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)) { + $url = get_the_post_thumbnail_url((int) $posts[0], 'medium_large'); + if ($url) { + return (string) $url; + } + } + return $default_fallback ? get_template_directory_uri() . '/assets/img/placeholder.svg' : ''; } endif; @@ -195,7 +215,7 @@ if (!function_exists('aksrt_widget_term_aggregation')) : $href = esc_url((string) $href); $icon = ''; - $img = aksrt_widget_term_cover_url((int) $term->term_id); + $img = aksrt_widget_term_cover_url((int) $term->term_id, true); $img_html = aksrt_graphic_card([ 'class' => '', 'img' => $img,