Align homepage and category discovery, modern widgets, admin controls, quotes, and comments with the reference theme. Remove superseded paths and add rendering and behavior coverage. Update stale asset and finance contracts; all 760 Node tests and 139 widget assertions pass.
682 lines
27 KiB
PHP
682 lines
27 KiB
PHP
<?php
|
|
/**
|
|
* Unified comments composition (legacy-style closed surface).
|
|
*
|
|
* comments.php stays a thin mount point. Policy + sections live here.
|
|
*
|
|
* @package AKSRT
|
|
*/
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
if (!function_exists('aksrt_comments_template_query_args')) :
|
|
/**
|
|
* Apply order / author-only filters to the comments template query.
|
|
*
|
|
* @param array<string,mixed> $args Comment query args.
|
|
* @return array<string,mixed>
|
|
*/
|
|
function aksrt_comments_template_query_args(array $args): array {
|
|
$order = isset($_GET['aksrt_comment_order'])
|
|
? sanitize_key((string) wp_unslash($_GET['aksrt_comment_order']))
|
|
: '';
|
|
if (!in_array($order, ['newest', 'hottest'], true)) {
|
|
$order = 'newest';
|
|
}
|
|
|
|
if ($order === 'hottest') {
|
|
$args['order'] = 'DESC';
|
|
$args['orderby'] = 'comment_date_gmt';
|
|
$args['aksrt_hottest_order'] = true;
|
|
} else {
|
|
$args['order'] = 'DESC';
|
|
$args['orderby'] = 'comment_date_gmt';
|
|
}
|
|
|
|
if (isset($_GET['aksrt_author_only']) && (int) wp_unslash($_GET['aksrt_author_only']) === 1) {
|
|
$post_id = (int) get_queried_object_id();
|
|
if ($post_id <= 0 && !empty($args['post_id'])) {
|
|
$post_id = (int) $args['post_id'];
|
|
}
|
|
$author_id = $post_id > 0 ? (int) get_post_field('post_author', $post_id) : 0;
|
|
if ($author_id > 0) {
|
|
$args['user_id'] = $author_id;
|
|
}
|
|
}
|
|
|
|
return $args;
|
|
}
|
|
endif;
|
|
|
|
add_filter('comments_template_query_args', static function ($args) {
|
|
if (!is_array($args)) {
|
|
$args = [];
|
|
}
|
|
return function_exists('aksrt_comments_template_query_args')
|
|
? aksrt_comments_template_query_args($args)
|
|
: $args;
|
|
});
|
|
|
|
add_filter('comments_clauses', static function (array $clauses, WP_Comment_Query $query): array {
|
|
if (empty($query->query_vars['aksrt_hottest_order'])) {
|
|
return $clauses;
|
|
}
|
|
|
|
global $wpdb;
|
|
$clauses['join'] .= " LEFT JOIN {$wpdb->commentmeta} AS aksrt_cm_hot ON ({$wpdb->comments}.comment_ID = aksrt_cm_hot.comment_id AND aksrt_cm_hot.meta_key = 'aksrt_comment_likes')";
|
|
$clauses['orderby'] = 'CAST(COALESCE(aksrt_cm_hot.meta_value, 0) AS UNSIGNED) DESC, ' . $wpdb->comments . '.comment_date_gmt DESC';
|
|
return $clauses;
|
|
}, 20, 2);
|
|
|
|
if (!function_exists('aksrt_comment_box_visible')) :
|
|
/**
|
|
* Whether the comment module may render for the current visitor.
|
|
*
|
|
* Mirrors the reference theme's comment_box_hide conditions.
|
|
*/
|
|
function aksrt_comment_box_visible(): bool {
|
|
$settings = class_exists('\AKSRT\Settings\Settings')
|
|
? \AKSRT\Settings\Settings::get_comment_display_settings()
|
|
: [];
|
|
$hide = sanitize_key((string) ($settings['box_hide'] ?? ''));
|
|
switch ($hide) {
|
|
case 'signin':
|
|
return is_user_logged_in();
|
|
case 'vip':
|
|
return function_exists('aksrt_is_vip') && aksrt_is_vip();
|
|
case 'vip_2':
|
|
return function_exists('aksrt_is_vip2') && aksrt_is_vip2();
|
|
case 'auth':
|
|
return function_exists('aksrt_current_user_is_verified') && aksrt_current_user_is_verified();
|
|
default:
|
|
return true;
|
|
}
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_build_context')) :
|
|
/**
|
|
* Resolve comments runtime context once.
|
|
*
|
|
* @return array<string,mixed>
|
|
*/
|
|
function aksrt_comments_build_context(): array {
|
|
$settings = class_exists('\AKSRT\Settings\Settings')
|
|
? \AKSRT\Settings\Settings::get_comment_display_settings()
|
|
: [
|
|
'order' => 'desc',
|
|
'nested_depth' => 3,
|
|
'require_login' => false,
|
|
'avatar_size' => 48,
|
|
];
|
|
|
|
$order = isset($_GET['aksrt_comment_order'])
|
|
? sanitize_key((string) wp_unslash($_GET['aksrt_comment_order']))
|
|
: 'newest';
|
|
if (!in_array($order, ['newest', 'hottest'], true)) {
|
|
$order = 'newest';
|
|
}
|
|
|
|
$avatar_size = max(24, (int) ($settings['avatar_size'] ?? 48));
|
|
$toolbar = is_array($settings['toolbar'] ?? null)
|
|
? $settings['toolbar']
|
|
: ['code' => true, 'image' => true];
|
|
|
|
return [
|
|
'settings' => $settings,
|
|
'comment_count' => (int) get_comments_number(),
|
|
'is_logged_in' => is_user_logged_in(),
|
|
'current_user' => wp_get_current_user(),
|
|
'require_login' => !empty($settings['require_login']),
|
|
'order' => $order,
|
|
'author_only' => isset($_GET['aksrt_author_only']) && (int) $_GET['aksrt_author_only'] === 1,
|
|
'post_author_id' => (int) get_the_author_meta('ID'),
|
|
'avatar_size' => $avatar_size,
|
|
'max_depth' => max(1, (int) ($settings['nested_depth'] ?? 3)),
|
|
'toolbar' => $toolbar,
|
|
'upload_enabled' => !empty($toolbar['upload_img']),
|
|
'link_enabled' => !empty($toolbar['link']),
|
|
'user_url_enabled' => !empty($settings['user_url']),
|
|
'box_placeholder' => (string) ($settings['box_placeholder'] ?? __('说点什么吧...', 'aksrt')),
|
|
'submit_text' => (string) ($settings['submit_text'] ?? __('提交评论', 'aksrt')),
|
|
'title_text' => (string) ($settings['title'] ?? __('评论', 'aksrt')),
|
|
'corderby_enabled' => !empty($settings['corderby']) && !empty($settings['like_enabled']),
|
|
'close_comments' => !empty($settings['close_comments']),
|
|
'box_hidden' => !aksrt_comment_box_visible(),
|
|
'oauth_providers' => class_exists('\AKSRT\Auth\OAuth')
|
|
? \AKSRT\Auth\OAuth::get_instance()->get_auth_providers_data()
|
|
: [],
|
|
];
|
|
}
|
|
endif;
|
|
|
|
|
|
if (!function_exists('aksrt_comments_normalize_order')) :
|
|
/**
|
|
* Normalize comment order key.
|
|
*/
|
|
function aksrt_comments_normalize_order(string $order = ''): string {
|
|
$order = sanitize_key($order);
|
|
if (!in_array($order, ['newest', 'hottest'], true)) {
|
|
$order = 'newest';
|
|
}
|
|
return $order;
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_query_for_post')) :
|
|
/**
|
|
* Shared comment query for first paint / fragment / load-more.
|
|
*
|
|
* @return array{comments:array<int,\WP_Comment>,total:int,max_pages:int,page:int,order:string,author_only:bool,settings:array}
|
|
*/
|
|
function aksrt_comments_query_for_post(int $post_id, array $args = []): array {
|
|
$settings = class_exists('\AKSRT\Settings\Settings')
|
|
? \AKSRT\Settings\Settings::get_comment_display_settings()
|
|
: [];
|
|
$order = aksrt_comments_normalize_order((string) ($args['order'] ?? ''));
|
|
$author_only = !empty($args['author_only']);
|
|
$page = max(1, (int) ($args['page'] ?? 1));
|
|
$per_page = max(1, (int) ($args['per_page'] ?? get_option('comments_per_page', 10)));
|
|
$include_unapproved_for_user = (int) ($args['include_unapproved_user'] ?? 0);
|
|
|
|
$query_args = [
|
|
'post_id' => $post_id,
|
|
'status' => 'approve',
|
|
'number' => $per_page,
|
|
'offset' => ($page - 1) * $per_page,
|
|
'orderby' => 'comment_date_gmt',
|
|
'order' => 'DESC',
|
|
'hierarchical' => 'threaded',
|
|
];
|
|
|
|
if ($author_only) {
|
|
$author_id = (int) get_post_field('post_author', $post_id);
|
|
if ($author_id > 0) {
|
|
$query_args['user_id'] = $author_id;
|
|
$query_args['hierarchical'] = false;
|
|
}
|
|
}
|
|
|
|
if ($include_unapproved_for_user > 0) {
|
|
// WP_Comment_Query does not support mixed status easily; keep approve only for list fragment.
|
|
}
|
|
|
|
if ($order === 'hottest') {
|
|
$query_args['aksrt_hottest_order'] = true;
|
|
}
|
|
|
|
$comment_query = new WP_Comment_Query($query_args);
|
|
$comments = is_array($comment_query->comments) ? $comment_query->comments : [];
|
|
|
|
// Pin reorder for page 1 when not author-only.
|
|
if ($page === 1 && !$author_only && function_exists('aksrt_reorder_pinned_comments')) {
|
|
$comments = aksrt_reorder_pinned_comments($comments, $post_id);
|
|
}
|
|
|
|
$count_args = [
|
|
'post_id' => $post_id,
|
|
'status' => 'approve',
|
|
'count' => true,
|
|
];
|
|
if ($author_only) {
|
|
$author_id = (int) get_post_field('post_author', $post_id);
|
|
if ($author_id > 0) {
|
|
$count_args['user_id'] = $author_id;
|
|
}
|
|
}
|
|
$total = (int) get_comments($count_args);
|
|
$max_pages = (int) max(1, (int) ceil($total / $per_page));
|
|
|
|
return [
|
|
'comments' => $comments,
|
|
'total' => $total,
|
|
'max_pages' => $max_pages,
|
|
'page' => $page,
|
|
'order' => $order,
|
|
'author_only' => $author_only,
|
|
'settings' => $settings,
|
|
'per_page' => $per_page,
|
|
];
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_render_items_html')) :
|
|
/**
|
|
* Render comment list items HTML via canonical callback.
|
|
*
|
|
* @param array<int,\WP_Comment> $comments
|
|
* @param array<string,mixed> $settings
|
|
* @param string $order
|
|
*/
|
|
function aksrt_comments_render_items_html(array $comments, array $settings = [], string $order = 'newest'): string {
|
|
if (empty($comments) || !function_exists('aksrt_comment_callback')) {
|
|
return '';
|
|
}
|
|
set_query_var('aksrt_comment_settings', $settings);
|
|
set_query_var('aksrt_comment_order', aksrt_comments_normalize_order($order));
|
|
|
|
$avatar = max(24, (int) ($settings['avatar_size'] ?? 48));
|
|
$depth = max(1, (int) ($settings['nested_depth'] ?? 3));
|
|
$reverse = $order === 'newest';
|
|
|
|
ob_start();
|
|
wp_list_comments([
|
|
'callback' => 'aksrt_comment_callback',
|
|
'style' => 'ol',
|
|
'avatar_size' => $avatar,
|
|
'max_depth' => $depth,
|
|
], $comments);
|
|
return (string) ob_get_clean();
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_render_single_html')) :
|
|
/**
|
|
* Render one comment item HTML.
|
|
*/
|
|
function aksrt_comments_render_single_html(\WP_Comment $comment, array $settings = []): string {
|
|
$html = aksrt_comments_render_items_html([$comment], $settings, 'newest');
|
|
return $html;
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_render_list_fragment')) :
|
|
/**
|
|
* Fragment payload for order/author/page AJAX.
|
|
*
|
|
* @return array{html:string,items_html:string,count_text:string,total:int,max_pages:int,page:int,order:string,author_only:bool,empty:bool}
|
|
*/
|
|
function aksrt_comments_render_list_fragment(int $post_id, array $args = []): array {
|
|
$result = aksrt_comments_query_for_post($post_id, $args);
|
|
$settings = $result['settings'];
|
|
$order = $result['order'];
|
|
$author_only = !empty($result['author_only']);
|
|
$page = (int) $result['page'];
|
|
$max_pages = (int) $result['max_pages'];
|
|
$total = (int) $result['total'];
|
|
|
|
// Fake globals needed by pagination helpers when not on singular loop.
|
|
$GLOBALS['post'] = get_post($post_id);
|
|
setup_postdata($GLOBALS['post']);
|
|
set_query_var('cpage', $page);
|
|
set_query_var('aksrt_comment_order', $order);
|
|
set_query_var('aksrt_comment_settings', $settings);
|
|
|
|
$items_html = aksrt_comments_render_items_html($result['comments'], $settings, $order);
|
|
|
|
$ctx = [
|
|
'order' => $order,
|
|
'author_only' => $author_only,
|
|
'post_author_id' => (int) get_post_field('post_author', $post_id),
|
|
'corderby_enabled' => !empty($settings['corderby']) && !empty($settings['like_enabled']),
|
|
'comment_count' => $total,
|
|
];
|
|
|
|
ob_start();
|
|
echo '<div id="postcomments"><ol class="commentlist list-unstyled">';
|
|
if ($items_html === '') {
|
|
if (function_exists('aksrt_comments_render_empty')) {
|
|
aksrt_comments_render_empty($ctx);
|
|
}
|
|
echo '<div class="pagenav hide"><div class="next-page ajax-next"><a href="#"></a></div></div>';
|
|
} else {
|
|
if (function_exists('aksrt_comments_render_filter') && !empty($ctx['corderby_enabled'])) {
|
|
aksrt_comments_render_filter($ctx);
|
|
}
|
|
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- rendered comment markup.
|
|
echo $items_html;
|
|
if (function_exists('aksrt_render_comment_pagination') && $max_pages > 1) {
|
|
$pages_filter = static function () use ($max_pages) {
|
|
return $max_pages;
|
|
};
|
|
add_filter('get_comment_pages_count', $pages_filter);
|
|
aksrt_render_comment_pagination();
|
|
remove_filter('get_comment_pages_count', $pages_filter);
|
|
}
|
|
}
|
|
echo '</ol></div>';
|
|
$list_html = (string) ob_get_clean();
|
|
|
|
wp_reset_postdata();
|
|
|
|
return [
|
|
'html' => $list_html,
|
|
'items_html' => $items_html,
|
|
'count_text' => sprintf(__('共%s条', 'aksrt'), (string) $total),
|
|
'total' => $total,
|
|
'max_pages' => $max_pages,
|
|
'page' => $page,
|
|
'order' => $order,
|
|
'author_only' => $author_only,
|
|
'empty' => $items_html === '',
|
|
];
|
|
}
|
|
endif;
|
|
|
|
|
|
if (!function_exists('aksrt_comments_render_signarea')) :
|
|
/**
|
|
* Login-required gate.
|
|
*
|
|
* @param array<string,mixed> $ctx Comments context.
|
|
*/
|
|
function aksrt_comments_render_signarea(array $ctx): void {
|
|
$oauth_providers = is_array($ctx['oauth_providers'] ?? null) ? $ctx['oauth_providers'] : [];
|
|
$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url(get_permalink()) : wp_login_url(get_permalink());
|
|
?>
|
|
<div class="comment-signarea text-center box-body radius8">
|
|
<h3 class="text-muted em12 theme-box muted-3-color"><?php esc_html_e('请登录后发表评论', 'aksrt'); ?></h3>
|
|
<p>
|
|
<a href="javascript:;" data-login-url="<?php echo esc_url($login_url); ?>" class="signin-loader but c-blue padding-lg"><i class="fa fas fa-fw fa-sign-in-alt mr10" aria-hidden="true"></i><?php esc_html_e('登录', 'aksrt'); ?></a>
|
|
<?php if (get_option('users_can_register')) :
|
|
$register_url = function_exists('aksrt_get_register_url') ? aksrt_get_register_url() : wp_registration_url();
|
|
?>
|
|
<a href="javascript:;" data-register-url="<?php echo esc_url($register_url); ?>" class="signup-loader ml10 but c-yellow padding-lg"><?php echo aksrt_get_comment_icon('signup', 'icon mr10'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- 固定 sprite 标记。 ?><?php esc_html_e('注册', 'aksrt'); ?></a>
|
|
<?php endif; ?>
|
|
</p>
|
|
<?php if (!empty($oauth_providers)) : ?>
|
|
<p class="social-login-wrap">
|
|
<?php foreach ($oauth_providers as $provider) :
|
|
$provider_name = (string) ($provider['name'] ?? '');
|
|
$label = (string) ($provider['label'] ?? $provider_name);
|
|
$url = (string) ($provider['url'] ?? '#');
|
|
$icon = $provider['icon'] ?? '';
|
|
?>
|
|
<a href="<?php echo esc_url($url); ?>" class="social-login-item but hollow ml10 <?php echo esc_attr($provider_name); ?>" data-provider="<?php echo esc_attr($provider_name); ?>" title="<?php echo esc_attr($label); ?>">
|
|
<?php echo $icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
|
<span><?php echo esc_html($label); ?></span>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_render_form')) :
|
|
/**
|
|
* Comment respond form.
|
|
*
|
|
* @param array<string,mixed> $ctx Comments context.
|
|
*/
|
|
function aksrt_comments_render_form(array $ctx): void {
|
|
$is_logged_in = !empty($ctx['is_logged_in']);
|
|
$current_user = $ctx['current_user'] ?? null;
|
|
$require_name_email = (bool) get_option('require_name_email');
|
|
$comment_author = isset($_COOKIE['comment_author_' . COOKIEHASH])
|
|
? sanitize_text_field(wp_unslash((string) $_COOKIE['comment_author_' . COOKIEHASH]))
|
|
: '';
|
|
$comment_email = isset($_COOKIE['comment_author_email_' . COOKIEHASH])
|
|
? sanitize_text_field(wp_unslash((string) $_COOKIE['comment_author_email_' . COOKIEHASH]))
|
|
: '';
|
|
$comment_author_url = isset($_COOKIE['comment_author_url_' . COOKIEHASH])
|
|
? esc_url_raw(wp_unslash((string) $_COOKIE['comment_author_url_' . COOKIEHASH]))
|
|
: '';
|
|
$placeholder = (string) $ctx['box_placeholder'];
|
|
$post_id = (int) get_the_ID();
|
|
$can_comment = function_exists('aksrt_user_can')
|
|
? aksrt_user_can('comment_add', get_current_user_id(), $post_id)
|
|
: $is_logged_in;
|
|
|
|
if (!$can_comment) {
|
|
if (!$is_logged_in) {
|
|
aksrt_comments_render_signarea($ctx);
|
|
} else {
|
|
// 治理状态区分提示(参考主题 zib_get_user_ban_nocan_info 语义:
|
|
// 禁封中/小黑屋/禁言显示状态徽章与查看入口,而非笼统的无权限文案)。
|
|
$ban_nocan = function_exists('aksrt_get_user_ban_nocan_html')
|
|
? aksrt_get_user_ban_nocan_html(get_current_user_id(), __('暂时无法发表评论', 'aksrt'))
|
|
: '';
|
|
if ($ban_nocan !== '') {
|
|
echo $ban_nocan; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- helper escapes internally.
|
|
} else {
|
|
echo '<p class="comments-permission-denied muted-2-color">' . esc_html__('当前账号没有发表评论的权限。', 'aksrt') . '</p>';
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (function_exists('aksrt_get_comment_virtual_input_html')) {
|
|
echo aksrt_get_comment_virtual_input_html($placeholder, '#respond'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
}
|
|
?>
|
|
<div id="respond" class="mobile-fixed">
|
|
<div class="fixed-body"></div>
|
|
<form id="commentform" method="post" action="<?php echo esc_url(site_url('/wp-comments-post.php')); ?>">
|
|
<div class="flex ac">
|
|
<div class="comt-title text-center flex0 mr10">
|
|
<?php if ($is_logged_in && $current_user instanceof WP_User) : ?>
|
|
<div class="comt-avatar mb10">
|
|
<?php echo aksrt_get_avatar_html($current_user->ID, 96, ['class' => 'avatar']); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- canonical avatar helper escapes output. ?>
|
|
</div>
|
|
<p class="text-ellipsis muted-2-color"><?php echo function_exists('aksrt_get_vip_icon') ? aksrt_get_vip_icon($current_user->ID, 'em12 mr3') : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- VIP helper escapes output. ?><?php echo esc_html($current_user->display_name); ?></p>
|
|
<?php else : ?>
|
|
<div class="comt-avatar mb10">
|
|
<?php echo aksrt_get_avatar_html(0, 96, ['class' => 'avatar']); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- canonical avatar helper escapes output. ?>
|
|
</div>
|
|
<p class="" data-toggle-class="open" data-target="#comment-user-info" data-toggle="tooltip" title="<?php esc_attr_e('填写用户信息', 'aksrt'); ?>">
|
|
<?php echo $comment_author !== '' ? esc_html($comment_author) : esc_html__('昵称', 'aksrt'); ?>
|
|
</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="comt-box grow1">
|
|
<div class="action-text mb10 em09 muted-2-color" id="comment-reply-info" style="display:none;"></div>
|
|
<textarea placeholder="<?php echo esc_attr($placeholder); ?>" autoheight="true" maxheight="188" class="form-control grin" name="comment" id="comment" cols="100%" rows="4" tabindex="1"></textarea>
|
|
<?php if (function_exists('aksrt_is_captcha_enabled_for') && function_exists('aksrt_render_captcha') && aksrt_is_captcha_enabled_for('comment')) : ?>
|
|
<div style="width: 230px; margin-top: 8px;"><?php aksrt_render_captcha('comment'); ?></div>
|
|
<?php endif; ?>
|
|
<div class="comt-ctrl relative">
|
|
<div class="comt-tips">
|
|
<?php comment_id_fields(); ?>
|
|
<?php wp_nonce_field('aksrt_comment_nonce', '_aksrt_comment_nonce'); ?>
|
|
<?php do_action('comment_form', get_the_ID()); ?>
|
|
</div>
|
|
<div class="comt-tips-right pull-right">
|
|
<a class="but c-red" id="cancel-comment-reply-link" href="javascript:;" style="display:none;"><?php esc_html_e('取消', 'aksrt'); ?></a>
|
|
<button class="but c-blue pw-1em input-expand-submit comment-send" name="submit" id="submit" type="submit" tabindex="5"><?php echo esc_html((string) $ctx['submit_text']); ?></button>
|
|
</div>
|
|
<div class="comt-tips-left">
|
|
<?php if (!$is_logged_in) :
|
|
$req_mark = $require_name_email ? '(' . __('必填', 'aksrt') . ')' : '';
|
|
?>
|
|
<span class="dropup relative" id="comment-user-info"<?php echo $require_name_email ? ' require_name_email="true"' : ''; ?>>
|
|
<a class="but mr6" data-toggle-class="open" data-target="#comment-user-info" href="javascript:;"><i class="fa fas fa-fw fa-user" aria-hidden="true"></i><span class="hide-sm"><?php esc_html_e('昵称', 'aksrt'); ?></span></a>
|
|
<div class="dropdown-menu box-body" style="width:250px;">
|
|
<div class="mb20">
|
|
<p><?php esc_html_e('请填写用户信息:', 'aksrt'); ?></p>
|
|
<ul>
|
|
<li class="line-form mb10">
|
|
<input type="text" name="author" class="line-form-input" tabindex="1" value="<?php echo esc_attr($comment_author); ?>" placeholder="">
|
|
<div class="scale-placeholder"><?php echo esc_html__('昵称', 'aksrt') . esc_html($req_mark); ?></div>
|
|
<div class="abs-right muted-color"><i class="fa fas fa-fw fa-user" aria-hidden="true"></i></div>
|
|
<i class="line-form-line"></i>
|
|
</li>
|
|
<li class="line-form">
|
|
<input type="text" name="email" class="line-form-input" tabindex="2" value="<?php echo esc_attr($comment_email); ?>" placeholder="">
|
|
<div class="scale-placeholder"><?php echo esc_html__('邮箱', 'aksrt') . esc_html($req_mark); ?></div>
|
|
<div class="abs-right muted-color"><i class="fa far fa-fw fa-envelope" aria-hidden="true"></i></div>
|
|
<i class="line-form-line"></i>
|
|
</li>
|
|
<?php if (!empty($ctx['user_url_enabled'])) : ?>
|
|
<li class="line-form">
|
|
<input type="text" name="url" class="line-form-input" tabindex="3" value="<?php echo esc_attr($comment_author_url); ?>" placeholder="">
|
|
<div class="scale-placeholder"><?php esc_html_e('博客地址', 'aksrt'); ?></div>
|
|
<div class="abs-right muted-color"><i class="fa fas fa-fw fa-link" aria-hidden="true"></i></div>
|
|
<i class="line-form-line"></i>
|
|
</li>
|
|
<?php endif; ?>
|
|
</ul>
|
|
</div>
|
|
<?php
|
|
$oauth = is_array($ctx['oauth_providers'] ?? null) ? $ctx['oauth_providers'] : [];
|
|
if (!empty($oauth)) :
|
|
?>
|
|
<p class="social-login-wrap">
|
|
<?php foreach ($oauth as $provider) :
|
|
$label = (string) ($provider['label'] ?? $provider['name'] ?? '');
|
|
$url = (string) ($provider['url'] ?? '#');
|
|
?>
|
|
<a href="<?php echo esc_url($url); ?>" class="but hollow social-login-item ml10"><?php echo esc_html($label); ?></a>
|
|
<?php endforeach; ?>
|
|
</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</span>
|
|
<?php endif; ?>
|
|
<?php if (function_exists('aksrt_render_comment_expand_toolbar')) { aksrt_render_comment_expand_toolbar($ctx); } ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<?php
|
|
}
|
|
endif;
|
|
|
|
|
|
if (!function_exists('aksrt_comments_render_filter')) :
|
|
/**
|
|
* Newest/hottest + author-only filter.
|
|
*
|
|
* @param array<string,mixed> $ctx Comments context.
|
|
*/
|
|
function aksrt_comments_render_filter(array $ctx): void {
|
|
if (empty($ctx['corderby_enabled'])) {
|
|
return;
|
|
}
|
|
$order = (string) $ctx['order'];
|
|
$author_only = !empty($ctx['author_only']);
|
|
$post_author_id = (int) $ctx['post_author_id'];
|
|
?>
|
|
<div class="comment-filter tab-nav-theme flex ac jsb" win-ajax-replace="comment-order-btn">
|
|
<ul class="list-inline comment-order-box" style="padding:0;">
|
|
<li class="mr6<?php echo $order === 'newest' ? ' active' : ''; ?>">
|
|
<a href="javascript:;" class="comment-orderby" data-order="newest" rel="nofollow"><?php esc_html_e('最新', 'aksrt'); ?></a>
|
|
</li>
|
|
<li class="<?php echo $order === 'hottest' ? 'active' : ''; ?>">
|
|
<a href="javascript:;" class="comment-orderby" data-order="hottest" rel="nofollow"><?php esc_html_e('最热', 'aksrt'); ?></a>
|
|
</li>
|
|
</ul>
|
|
<?php if ($post_author_id > 0) : ?>
|
|
<a href="javascript:;" class="but comment-orderby btn-only-author p2-10" data-author-only="<?php echo $author_only ? '0' : '1'; ?>" rel="nofollow">
|
|
<?php echo $author_only ? esc_html__('查看全部', 'aksrt') : esc_html__('只看作者', 'aksrt'); ?>
|
|
</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_get_comment_ajax_loader')) :
|
|
/**
|
|
* Hidden skeleton loader shown while AJAX pagination runs (legacy parity).
|
|
*
|
|
* @return string
|
|
*/
|
|
function aksrt_get_comment_ajax_loader(): string {
|
|
$item = '<ul class="list-inline flex"><div class="avatar-img placeholder radius"></div><li class="flex1"><div class="placeholder s1 mb6" style="width: 30%;"></div><div class="placeholder k2 mb10"></div><i class="placeholder s1 mb6"></i><i class="placeholder s1 mb6 ml10"></i></li></ul>';
|
|
// 显隐交给 modal-runtime.css 的 .is-loading,内联 display:none 会让骨架永远无法展开。
|
|
return '<div class="post_ajax_loader">' . $item . $item . $item . $item . '</div>';
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_render_empty')) :
|
|
/**
|
|
* Empty state (legacy: legacy('暂无评论内容', 40, 'null.svg', 'comment comment-null')).
|
|
*
|
|
* @param array<string,mixed> $ctx Comments context.
|
|
*/
|
|
function aksrt_comments_render_empty(array $ctx): void {
|
|
$text = __('暂无评论内容', 'aksrt');
|
|
if (function_exists('aksrt_get_null')) {
|
|
echo aksrt_get_null($text, 40, 'comment-null.svg', 'comment comment-null', 280); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
return;
|
|
}
|
|
echo '<div class="text-center comment comment-null" style="padding:40px 0;"><p class="em09 muted-3-color separator">' . esc_html($text) . '</p></div>';
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_render')) :
|
|
/**
|
|
* Compose the full comments surface.
|
|
*/
|
|
function aksrt_comments_render(): void {
|
|
if (post_password_required() || !comments_open()) {
|
|
return;
|
|
}
|
|
|
|
$ctx = aksrt_comments_build_context();
|
|
if (!empty($ctx['close_comments']) || !empty($ctx['box_hidden'])) {
|
|
return;
|
|
}
|
|
|
|
set_query_var('aksrt_comment_order', (string) $ctx['order']);
|
|
set_query_var('aksrt_comment_settings', $ctx['settings']);
|
|
|
|
$count = (int) $ctx['comment_count'];
|
|
$count_label = $count > 0
|
|
? sprintf(__('共%s条', 'aksrt'), (string) $count)
|
|
: __('抢沙发', 'aksrt');
|
|
?>
|
|
<div class="theme-box" id="comments" data-post-id="<?php echo esc_attr((string) get_the_ID()); ?>">
|
|
<div class="box-body notop">
|
|
<div class="title-theme"><?php echo esc_html((string) $ctx['title_text']); ?>
|
|
<?php echo '<small>' . esc_html($count_label) . '</small>'; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="no_webshot main-bg theme-box box-body radius8 main-shadow">
|
|
<?php if (!empty($ctx['require_login']) && empty($ctx['is_logged_in'])) : ?>
|
|
<?php aksrt_comments_render_signarea($ctx); ?>
|
|
<?php else : ?>
|
|
<?php aksrt_comments_render_form($ctx); ?>
|
|
<?php endif; ?>
|
|
|
|
<div id="postcomments">
|
|
<ol class="commentlist list-unstyled">
|
|
<?php
|
|
$show_filter = !empty($ctx['corderby_enabled']) && have_comments();
|
|
if ($show_filter) {
|
|
aksrt_comments_render_filter($ctx);
|
|
}
|
|
|
|
if (have_comments()) {
|
|
aksrt_comments_render_list_items($ctx);
|
|
} else {
|
|
aksrt_comments_render_empty($ctx);
|
|
echo '<div class="pagenav hide"><div class="next-page ajax-next"><a href="#"></a></div></div>';
|
|
}
|
|
?>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_render_list_items')) :
|
|
/**
|
|
* Render just the comment items + loader + pagination (inside ol.commentlist).
|
|
*
|
|
* @param array<string,mixed> $ctx Comments context.
|
|
*/
|
|
function aksrt_comments_render_list_items(array $ctx): void {
|
|
wp_list_comments([
|
|
'type' => 'comment',
|
|
'style' => 'ol',
|
|
'avatar_size' => (int) $ctx['avatar_size'],
|
|
'max_depth' => (int) $ctx['max_depth'],
|
|
'callback' => 'aksrt_comment_callback',
|
|
]);
|
|
echo aksrt_get_comment_ajax_loader(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
if (function_exists('aksrt_render_comment_pagination')) {
|
|
aksrt_render_comment_pagination();
|
|
}
|
|
}
|
|
endif;
|
|
|