feat(identity): author card, per-user tip, comment caps, task status

Author card uses configurable limit/orderby/style and self CTAs.
Tip is per-user weixin/alipay QR modal (no site-global image).
Comment action permissions honor user_caps matrix.
Free points tasks expose done_today/passive status + better comment deep link.
audit-admin-contracts errors=0.
This commit is contained in:
2026-07-17 01:21:35 +08:00
parent b4d04ae346
commit 8d4e94a02c
10 changed files with 374 additions and 148 deletions
+1
View File
@@ -45,6 +45,7 @@ require_once AKSRT_DIR . '/inc/helpers/aksrt-coupon-order.php';
require_once AKSRT_DIR . '/inc/helpers/aksrt-credits.php';
require_once AKSRT_DIR . '/inc/helpers/aksrt-null.php';
require_once AKSRT_DIR . '/inc/helpers/aksrt-identity.php';
require_once AKSRT_DIR . '/inc/helpers/aksrt-rewards.php';
require_once AKSRT_DIR . '/inc/helpers/menu-decoration.php';
require_once AKSRT_DIR . '/inc/helpers/class-aksrt-nav-walker.php';
require_once AKSRT_DIR . '/inc/helpers/aksrt-transactions.php';
@@ -75,6 +75,17 @@ class AKSRT_Admin_Schema_Post_List {
['key' => 'breadcrumbs_single_text', 'label' => '末项显示「正文」', 'type' => 'switch', 'default' => true, 'depends_on' => 'breadcrumbs_single_s', 'description' => '关闭后末项显示文章标题'],
['key' => 'post_prevnext_s', 'label' => '上一篇/下一篇', 'type' => 'switch', 'default' => true],
['key' => 'post_authordesc_s', 'label' => '作者简介', 'type' => 'switch', 'default' => true],
['key' => 'post_author_card_limit', 'label' => '作者卡文章数', 'type' => 'number', 'default' => 6, 'min' => 0, 'max' => 12],
['key' => 'post_author_card_orderby', 'label' => '作者卡文章排序', 'type' => 'select', 'default' => 'views', 'options' => [
['label' => '浏览量', 'value' => 'views'],
['label' => '发布时间', 'value' => 'date'],
['label' => '更新时间', 'value' => 'modified'],
['label' => '评论数', 'value' => 'comment_count'],
]],
['key' => 'post_author_card_style', 'label' => '作者卡文章样式', 'type' => 'radio', 'default' => 'card', 'options' => [
['label' => '卡片', 'value' => 'card'],
['label' => '列表', 'value' => 'list'],
]],
['key' => 'post_single_hide_time_s', 'label' => '隐藏文章时间', 'type' => 'switch', 'default' => false],
]],
['key' => 'cover', 'title' => '封面展示', 'fields' => [
@@ -127,8 +138,8 @@ class AKSRT_Admin_Schema_Post_List {
['key' => 'post_copyright_enabled', 'label' => '版权信息', 'type' => 'switch', 'default' => true],
['key' => 'post_copyright_text', 'label' => '版权默认文案', 'type' => 'textarea', 'default' => '', 'description' => '留空则自动生成"本文由 XX 原创发布"'],
['key' => 'post_wechat_share', 'label' => '微信分享', 'type' => 'switch', 'default' => false],
['key' => 'post_rewards_enabled', 'label' => '打赏功能', 'type' => 'switch', 'default' => false],
['key' => 'post_rewards_text', 'label' => '打赏文案', 'type' => 'input', 'default' => ''],
['key' => 'post_rewards_s', 'label' => '用户打赏', 'type' => 'switch', 'default' => false],
['key' => 'post_rewards_text', 'label' => '打赏按钮文案', 'type' => 'input', 'default' => '赞赏'],
['key' => 'post_button_toptext', 'label' => '按钮上方文案', 'type' => 'input', 'default' => '喜欢就支持一下吧'],
]],
['key' => 'content', 'title' => '内容处理', 'fields' => [
+18 -6
View File
@@ -180,9 +180,12 @@ class AKSRT_Points_Free {
* @return list<array{key:string,title:string,desc:string,points:int,enabled:bool}>
*/
public static function task_list_for_user(int $user_id = 0): array {
unset($user_id); // reserved for per-user progress later
$cfg = self::settings();
$list = [];
$login_done = false;
if ($user_id > 0) {
$login_done = (string) get_user_meta($user_id, self::META_LOGIN, true) === self::today_key();
}
foreach (self::catalog() as $key => $meta) {
$pts = (int) ($cfg['tasks'][$key] ?? 0);
// Hide sign_up from daily task list (one-time); still grant on register.
@@ -192,12 +195,21 @@ class AKSRT_Points_Free {
if ($pts <= 0) {
continue;
}
$status = 'todo';
if (in_array($key, ['login', 'sign_in'], true) && $login_done) {
$status = 'done_today';
} elseif (in_array($key, ['post_like', 'post_favorite', 'followed', 'comment_like', 'bbs_essence', 'bbs_adopt', 'bbs_posts_hot', 'bbs_comment_hot', 'bbs_score_extra'], true)) {
$status = 'passive';
}
$list[] = [
'key' => $key,
'title' => $meta[0],
'desc' => $meta[1],
'points' => $pts,
'enabled' => true,
'key' => $key,
'title' => $meta[0],
'desc' => $meta[1],
'points' => $pts,
'enabled' => true,
'status' => $status,
'progress' => null,
'target' => null,
];
}
return $list;
@@ -237,10 +237,20 @@ class AKSRT_Settings_Post_Display {
$authordesc = !isset($settings['post_authordesc_s']) || !empty($settings['post_authordesc_s']);
$hide_time = !empty($settings['post_single_hide_time_s']);
$share_enabled = !isset($settings['share_s']) || !empty($settings['share_s']);
$rewards_enabled = !empty($settings['post_rewards_enabled']) || !empty($settings['post_rewards_s']);
$rewards_image = (string) ($settings['post_rewards_image'] ?? $settings['post_rewards_qrcode'] ?? $settings['post_rewards_img'] ?? '');
$rewards_enabled = !empty($settings['post_rewards_s']) || !empty($settings['post_rewards_enabled']);
$rewards_text = sanitize_text_field((string) ($settings['post_rewards_text'] ?? ''));
$rewards_btn_text = sanitize_text_field((string) ($settings['post_rewards_btn_text'] ?? '赞赏'));
if ($rewards_text === '') {
$rewards_text = '赞赏';
}
$author_card_limit = max(0, min(12, (int) ($settings['post_author_card_limit'] ?? 6)));
$author_card_orderby = sanitize_key((string) ($settings['post_author_card_orderby'] ?? 'views'));
if (!in_array($author_card_orderby, ['views', 'date', 'modified', 'comment_count'], true)) {
$author_card_orderby = 'views';
}
$author_card_style = sanitize_key((string) ($settings['post_author_card_style'] ?? 'card'));
if (!in_array($author_card_style, ['card', 'list'], true)) {
$author_card_style = 'card';
}
$maxheight_enabled = !empty($settings['article_maxheight_kg'])
|| !empty($settings['post_article_maxheight_kg'])
|| !empty($settings['post_maxheight_kg']);
@@ -318,11 +328,15 @@ class AKSRT_Settings_Post_Display {
// Canonical + legacy share.
'share_enabled' => $share_enabled,
'share_s' => $share_enabled,
// Rewards (Zibll post_rewards_s).
// Author card posts (Zibll user_card_box defaults).
'author_card_limit' => $author_card_limit,
'author_card_orderby' => $author_card_orderby,
'author_card_style' => $author_card_style,
// Rewards (Zibll post_rewards_s) — per-user QR only.
'rewards_enabled' => $rewards_enabled,
'rewards_image' => $rewards_image,
'post_rewards_s' => $rewards_enabled,
'rewards_text' => $rewards_text,
'rewards_btn_text' => $rewards_btn_text !== '' ? $rewards_btn_text : '赞赏',
'rewards_btn_text' => $rewards_text,
// Content max height (Zibll article_maxheight_kg / article_maxheight).
'maxheight_enabled' => $maxheight_enabled,
'maxheight' => $maxheight,
+52 -21
View File
@@ -835,28 +835,59 @@ if (!function_exists('aksrt_comment_action_permissions')) :
* @return array{can_edit:bool,can_delete:bool,can_moderate:bool,can_pin:bool}
*/
function aksrt_comment_action_permissions($comment): array {
$comment = $comment instanceof WP_Comment ? $comment : get_comment($comment);
$none = ['can_edit' => false, 'can_delete' => false, 'can_moderate' => false, 'can_pin' => false];
if (!($comment instanceof WP_Comment) || !is_user_logged_in()) {
return $none;
$comment = $comment instanceof WP_Comment ? $comment : get_comment($comment);
$none = ['can_edit' => false, 'can_delete' => false, 'can_moderate' => false, 'can_pin' => false];
if (!($comment instanceof WP_Comment) || !is_user_logged_in()) {
return $none;
}
$uid = get_current_user_id();
$is_wp_mod = current_user_can('moderate_comments') || current_user_can('manage_options');
$is_owner = (int) $comment->user_id > 0 && (int) $comment->user_id === $uid;
$post_id = (int) $comment->comment_post_ID;
$post = $post_id > 0 ? get_post($post_id) : null;
$is_post_author = $post instanceof WP_Post && (int) $post->post_author === $uid;
$ctx = $post_id > 0 ? $post_id : null;
$can = static function (string $cap) use ($uid, $ctx): bool {
if (function_exists('aksrt_user_can')) {
return aksrt_user_can($cap, $uid, $ctx);
}
if (class_exists('AKSRT_Settings_Capabilities')) {
return AKSRT_Settings_Capabilities::user_can($cap, $uid, $ctx);
}
return false;
};
$edit_window = 10;
if (class_exists('AKSRT_Settings')) {
$display = AKSRT_Settings::get_comment_display_settings();
$edit_window = (int) ($display['edit_window'] ?? 10);
}
$within_window = $edit_window > 0
&& (time() - strtotime((string) $comment->comment_date_gmt)) < ($edit_window * MINUTE_IN_SECONDS);
$can_edit_own = $is_owner && $within_window && $can('comment_edit');
$can_edit_others = (!$is_owner) && (
($is_post_author && $can('comment_edit_my_post'))
|| $can('comment_edit_other')
);
$can_delete_own = $is_owner && $can('comment_delete');
$can_delete_others = (!$is_owner) && (
($is_post_author && $can('comment_delete_my_post'))
|| $can('comment_delete_other')
);
$can_pin = (int) $comment->comment_parent === 0 && (
($is_post_author && $can('comment_set_topping_my_post'))
|| $can('comment_set_topping_other')
);
return [
'can_edit' => $is_wp_mod || $can_edit_own || $can_edit_others,
'can_delete' => $is_wp_mod || $can_delete_own || $can_delete_others,
'can_moderate' => $is_wp_mod || $can('comment_audit_other') || ($is_post_author && $can('comment_audit_my_post')),
'can_pin' => $is_wp_mod || $can_pin,
];
}
$is_moderator = current_user_can('moderate_comments');
$is_owner = (int) $comment->user_id > 0 && (int) $comment->user_id === get_current_user_id();
// Owner self-edit window (minutes); moderators bypass the window.
$edit_window = 10;
if (class_exists('AKSRT_Settings')) {
$display = AKSRT_Settings::get_comment_display_settings();
$edit_window = (int) ($display['edit_window'] ?? 10);
}
$within_window = $edit_window > 0
&& (time() - strtotime((string) $comment->comment_date_gmt)) < ($edit_window * MINUTE_IN_SECONDS);
return [
'can_edit' => $is_moderator || ($is_owner && $within_window),
'can_delete' => $is_moderator || $is_owner,
'can_moderate' => $is_moderator,
'can_pin' => $is_moderator && (int) $comment->comment_parent === 0,
];
}
endif;
if (!function_exists('aksrt_is_comment_pinned')) :
/**
+113
View File
@@ -0,0 +1,113 @@
<?php
/**
* Per-user tip (打赏) helpers — Zibll post_rewards_s + user QR parity.
*
* Meta: aksrt_rewards_weixin, aksrt_rewards_alipay (attachment id or URL).
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
if (!function_exists('aksrt_rewards_enabled')) {
function aksrt_rewards_enabled(): bool {
if (!class_exists('AKSRT_Settings') || !method_exists('AKSRT_Settings', 'get_post_page_settings')) {
return false;
}
$s = AKSRT_Settings::get_post_page_settings();
return !empty($s['rewards_enabled']) || !empty($s['post_rewards_s']);
}
}
if (!function_exists('aksrt_get_user_rewards_img_urls')) {
/**
* @return array{weixin:string,alipay:string}
*/
function aksrt_get_user_rewards_img_urls(int $user_id): array {
$out = ['weixin' => '', 'alipay' => ''];
if ($user_id <= 0) {
return $out;
}
foreach (['weixin' => 'aksrt_rewards_weixin', 'alipay' => 'aksrt_rewards_alipay'] as $key => $meta) {
$raw = get_user_meta($user_id, $meta, true);
if (is_numeric($raw) && (int) $raw > 0) {
$url = wp_get_attachment_image_url((int) $raw, 'full');
$out[$key] = is_string($url) ? $url : '';
} else {
$out[$key] = esc_url_raw((string) $raw);
}
}
return $out;
}
}
if (!function_exists('aksrt_user_has_rewards_qr')) {
function aksrt_user_has_rewards_qr(int $user_id): bool {
$urls = aksrt_get_user_rewards_img_urls($user_id);
return $urls['weixin'] !== '' || $urls['alipay'] !== '';
}
}
if (!function_exists('aksrt_get_rewards_button')) {
function aksrt_get_rewards_button(int $user_id, string $class = 'but jb-blue ml10 pw-1em'): string {
if ($user_id <= 0 || !aksrt_rewards_enabled() || !aksrt_user_has_rewards_qr($user_id)) {
return '';
}
$label = '赞赏';
if (class_exists('AKSRT_Settings') && method_exists('AKSRT_Settings', 'get_post_page_settings')) {
$s = AKSRT_Settings::get_post_page_settings();
$label = (string) ($s['rewards_btn_text'] ?? $s['rewards_text'] ?? $label);
if ($label === '') {
$label = '赞赏';
}
}
return '<button type="button" class="' . esc_attr($class) . ' aksrt-reward-open" data-aksrt-reward-open data-user-id="' . (int) $user_id . '"><i class="fa fa-gift em09" aria-hidden="true"></i> ' . esc_html($label) . '</button>';
}
}
if (!function_exists('aksrt_render_rewards_modal_for_user')) {
function aksrt_render_rewards_modal_for_user(int $user_id): void {
static $done = [];
if ($user_id <= 0 || isset($done[$user_id])) {
return;
}
if (!aksrt_rewards_enabled() || !aksrt_user_has_rewards_qr($user_id)) {
return;
}
$done[$user_id] = true;
$urls = aksrt_get_user_rewards_img_urls($user_id);
$label = '赞赏';
if (class_exists('AKSRT_Settings') && method_exists('AKSRT_Settings', 'get_post_page_settings')) {
$s = AKSRT_Settings::get_post_page_settings();
$label = (string) ($s['rewards_text'] ?? $label);
if ($label === '') {
$label = __('赞赏', 'aksrt');
}
}
?>
<div class="reward-modal" id="reward-modal-<?php echo (int) $user_id; ?>" data-user-id="<?php echo (int) $user_id; ?>" aria-hidden="true">
<div class="reward-modal__overlay" data-aksrt-reward-close></div>
<div class="reward-modal__dialog" role="dialog" aria-modal="true">
<button type="button" class="reward-modal__close" data-aksrt-reward-close aria-label="<?php esc_attr_e('关闭', 'aksrt'); ?>"><i class="fas fa-times" aria-hidden="true"></i></button>
<div class="reward-modal__content">
<h3><?php echo esc_html($label); ?></h3>
<div class="reward-modal__qrcodes flex jc ac hh">
<?php if ($urls['weixin'] !== '') : ?>
<div class="reward-modal__qrcode text-center mr10">
<img src="<?php echo esc_url($urls['weixin']); ?>" alt="<?php esc_attr_e('微信收款码', 'aksrt'); ?>" loading="lazy" decoding="async" />
<div class="em09 muted-2-color mt6"><?php esc_html_e('微信', 'aksrt'); ?></div>
</div>
<?php endif; ?>
<?php if ($urls['alipay'] !== '') : ?>
<div class="reward-modal__qrcode text-center">
<img src="<?php echo esc_url($urls['alipay']); ?>" alt="<?php esc_attr_e('支付宝收款码', 'aksrt'); ?>" loading="lazy" decoding="async" />
<div class="em09 muted-2-color mt6"><?php esc_html_e('支付宝', 'aksrt'); ?></div>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php
}
}
+108 -30
View File
@@ -240,7 +240,23 @@ if (!function_exists('aksrt_single_render_actions')) :
</button>
<?php endif; ?>
<?php if (!empty($settings['rewards_enabled']) && !empty($settings['rewards_image'])) : ?>
<?php
$reward_author = (int) get_the_author_meta('ID');
$reward_btn = ($reward_author > 0 && function_exists('aksrt_get_rewards_button'))
? aksrt_get_rewards_button($reward_author, 'action action-rewards')
: '';
if ($reward_btn === '' && !empty($settings['rewards_enabled']) && function_exists('aksrt_user_has_rewards_qr') && $reward_author > 0 && aksrt_user_has_rewards_qr($reward_author)) {
$label = esc_html((string) ($settings['rewards_btn_text'] ?? __('赞赏', 'aksrt')));
$reward_btn = '<button type="button" class="action action-rewards" data-aksrt-reward-open data-user-id="' . (int) $reward_author . '"><i class="fas fa-gift" aria-hidden="true"></i><span class="action-btn__label">' . $label . '</span></button>';
}
if ($reward_btn !== '') :
echo $reward_btn; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
if (function_exists('aksrt_render_rewards_modal_for_user')) {
aksrt_render_rewards_modal_for_user($reward_author);
}
endif;
// legacy placeholder to keep structure; actual button echoed above
if (false) : ?>
<button type="button" class="action action-rewards" id="action-reward">
<i class="fas fa-gift" aria-hidden="true"></i>
<span class="action-btn__label"><?php echo esc_html($settings['rewards_btn_text'] ?? __('赞赏', 'aksrt')); ?></span>
@@ -348,15 +364,42 @@ if (!function_exists('aksrt_single_render_author_card')) :
$avatar = function_exists('aksrt_get_avatar_html')
? aksrt_get_avatar_html($author_id, 80, ['class' => 'avatar avatar-lg'])
: get_avatar($author_id, 80, '', esc_attr($author_name), ['class' => 'avatar avatar-lg']);
$recent = get_posts([
'author' => $author_id,
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 6,
'orderby' => 'date',
'order' => 'DESC',
'no_found_rows' => true,
]);
$page_s = class_exists('AKSRT_Settings') && method_exists('AKSRT_Settings', 'get_post_page_settings')
? AKSRT_Settings::get_post_page_settings()
: [];
$card_limit = max(0, min(12, (int) ($page_s['author_card_limit'] ?? 6)));
$card_orderby = sanitize_key((string) ($page_s['author_card_orderby'] ?? 'views'));
$card_style = sanitize_key((string) ($page_s['author_card_style'] ?? 'card'));
$recent = [];
if ($card_limit > 0) {
$q = [
'author' => $author_id,
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => $card_limit,
'ignore_sticky_posts' => true,
'no_found_rows' => true,
];
$cur = get_the_ID();
if ($cur) {
$q['post__not_in'] = [(int) $cur];
}
if ($card_orderby === 'views') {
$q['meta_key'] = 'views';
$q['orderby'] = 'meta_value_num';
$q['order'] = 'DESC';
} elseif ($card_orderby === 'comment_count') {
$q['orderby'] = 'comment_count';
$q['order'] = 'DESC';
} elseif ($card_orderby === 'modified') {
$q['orderby'] = 'modified';
$q['order'] = 'DESC';
} else {
$q['orderby'] = 'date';
$q['order'] = 'DESC';
}
$recent = get_posts($q);
}
$is_self = is_user_logged_in() && get_current_user_id() === $author_id;
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url() : wp_login_url(get_permalink());
$aksrt_pm_on = class_exists('AKSRT_Settings') && !empty(AKSRT_Settings::private_message_settings()['enabled']);
@@ -387,7 +430,20 @@ if (!function_exists('aksrt_single_render_author_card')) :
<div class="user-desc mt10 muted-2-color em09"><?php echo esc_html($bio); ?></div>
<?php endif; ?>
<div class="user-btns mt20">
<?php if (!$is_self) : ?>
<?php if ($is_self) : ?>
<?php
$submit = function_exists('aksrt_get_page_url_by_template')
? (string) aksrt_get_page_url_by_template('templates/pages/page-submit.php')
: '';
$center = function_exists('aksrt_get_user_center_url')
? (string) aksrt_get_user_center_url()
: $author_url;
if ($submit !== '') :
?>
<a class="but pw-1em mr6 jb-pink" href="<?php echo esc_url($submit); ?>"><?php esc_html_e('发布文章', 'aksrt'); ?></a>
<?php endif; ?>
<a class="but pw-1em mr6 jb-blue" href="<?php echo esc_url($center); ?>"><?php esc_html_e('用户中心', 'aksrt'); ?></a>
<?php else : ?>
<?php if (is_user_logged_in()) : ?>
<button type="button" class="but pw-1em mr6 c-red follow" data-aksrt-follow="<?php echo (int) $author_id; ?>">
<i class="fa fa-heart em09" aria-hidden="true"></i> <span><?php esc_html_e('关注', 'aksrt'); ?></span>
@@ -397,34 +453,56 @@ if (!function_exists('aksrt_single_render_author_card')) :
<i class="fa fa-heart em09" aria-hidden="true"></i> <span><?php esc_html_e('关注', 'aksrt'); ?></span>
</a>
<?php endif; ?>
<?php if (is_user_logged_in() && $aksrt_pm_on && $aksrt_msg_url !== '') : ?>
<a class="but pw-1em mr6 c-blue" href="<?php echo esc_url(add_query_arg('msg_type', 'conversation', $aksrt_msg_url)); ?>">
<i class="fa fa-comment em09" aria-hidden="true"></i> <?php esc_html_e('私信', 'aksrt'); ?>
</a>
<?php endif; ?>
<?php
$tip = function_exists('aksrt_get_rewards_button') ? aksrt_get_rewards_button($author_id, 'but pw-1em mr6 c-yellow') : '';
if ($tip !== '') {
echo $tip; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
if (function_exists('aksrt_render_rewards_modal_for_user')) {
aksrt_render_rewards_modal_for_user($author_id);
}
}
?>
<a class="but pw-1em mr6 jb-blue" href="<?php echo esc_url($author_url); ?>"><?php esc_html_e('个人主页', 'aksrt'); ?></a>
<?php endif; ?>
<?php if (!$is_self && is_user_logged_in() && $aksrt_pm_on && $aksrt_msg_url !== '') : ?>
<a class="but pw-1em mr6 c-blue" href="<?php echo esc_url(add_query_arg('msg_type', 'conversation', $aksrt_msg_url)); ?>">
<i class="fa fa-comment em09" aria-hidden="true"></i> <?php esc_html_e('私信', 'aksrt'); ?>
</a>
<?php elseif (!$is_self && $rewards_on) : ?>
<button type="button" class="but pw-1em mr6 c-yellow" data-aksrt-reward-open>
<i class="fa fa-gift em09" aria-hidden="true"></i> <?php esc_html_e('赞赏', 'aksrt'); ?>
</button>
<?php endif; ?>
<a class="but pw-1em mr6 jb-blue" href="<?php echo esc_url($author_url); ?>"><?php esc_html_e('个人主页', 'aksrt'); ?></a>
</div>
</div>
</div>
<?php if (!empty($recent)) : ?>
<div class="user-card-posts mt10">
<ul class="no-thumb">
<?php foreach ($recent as $rp) : ?>
<?php if ($rp instanceof WP_Post) : ?>
<li><a class="icon-circle" href="<?php echo esc_url(get_permalink($rp)); ?>"><?php echo esc_html(get_the_title($rp)); ?></a></li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
<?php if ($card_style === 'card') : ?>
<div class="more-posts-mini flex hh">
<?php foreach ($recent as $rp) : ?>
<?php if ($rp instanceof WP_Post) :
$thumb = get_the_post_thumbnail_url($rp, 'medium');
?>
<a class="item mr10 mb10" href="<?php echo esc_url(get_permalink($rp)); ?>" style="display:block;width:46%;">
<?php if ($thumb) : ?>
<img class="fit-cover radius8" src="<?php echo esc_url($thumb); ?>" alt="" loading="lazy" decoding="async" style="width:100%;aspect-ratio:16/10;object-fit:cover;" />
<?php endif; ?>
<div class="em09 mt6 text-ellipsis"><?php echo esc_html(get_the_title($rp)); ?></div>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
<?php else : ?>
<ul class="no-thumb">
<?php foreach ($recent as $rp) : ?>
<?php if ($rp instanceof WP_Post) : ?>
<li><a class="icon-circle" href="<?php echo esc_url(get_permalink($rp)); ?>"><?php echo esc_html(get_the_title($rp)); ?></a></li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
<?php else : ?>
<div class="user-card-posts mt10 muted-2-color em09 text-center"><?php esc_html_e('暂无更多文章', 'aksrt'); ?></div>
<?php endif; ?>
</div>
<?php endif;
?> </div>
</div>
<?php
}
@@ -167,8 +167,10 @@ $pane = isset($points_tasks_pane) ? sanitize_key((string) $points_tasks_pane)
<?php
$task_key = sanitize_key((string) ($task['key'] ?? ''));
$action = $aksrt_points_task_action($task_key);
$status = sanitize_key((string) ($task['status'] ?? 'todo'));
$done = in_array($status, ['done_today', 'done'], true);
?>
<div class="border-bottom padding-h10 uc-points-tasks__row" data-task-key="<?php echo esc_attr($task_key); ?>">
<div class="border-bottom padding-h10 uc-points-tasks__row<?php echo $done ? ' is-done' : ''; ?>" data-task-key="<?php echo esc_attr($task_key); ?>" data-status="<?php echo esc_attr($status); ?>">
<div class="flex jsb ac">
<div class="flex1 mr20">
<div class="font-bold mb6"><?php echo esc_html((string) $task['title']); ?></div>