323 lines
14 KiB
PHP
323 lines
14 KiB
PHP
<?php
|
|
/**
|
|
* Unified comments composition (Zibll-style closed surface).
|
|
*
|
|
* comments.php stays a thin mount point. Policy + sections live here.
|
|
*
|
|
* @package AKSRT
|
|
*/
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
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')
|
|
? AKSRT_Settings::get_comment_display_settings()
|
|
: [
|
|
'order' => 'desc',
|
|
'nested_depth' => 3,
|
|
'require_login' => false,
|
|
'allow_reply' => true,
|
|
'avatar_size' => 48,
|
|
'empty_text' => __('暂无评论,来做第一个评论的人吧~', 'aksrt'),
|
|
];
|
|
|
|
$default_order = (($settings['order'] ?? 'desc') === 'asc') ? 'oldest' : 'newest';
|
|
$order = isset($_GET['aksrt_comment_order'])
|
|
? sanitize_key((string) wp_unslash($_GET['aksrt_comment_order']))
|
|
: $default_order;
|
|
if (!in_array($order, ['newest', 'oldest', 'hottest'], true)) {
|
|
$order = 'newest';
|
|
}
|
|
|
|
$avatar_size = max(24, (int) ($settings['avatar_size'] ?? 48));
|
|
$toolbar = is_array($settings['toolbar'] ?? null)
|
|
? $settings['toolbar']
|
|
: ['smilie' => true, '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,
|
|
'reverse_comments' => $order === 'newest',
|
|
'is_hottest' => $order === 'hottest',
|
|
'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)),
|
|
'allow_reply' => !empty($settings['allow_reply']),
|
|
'empty_text' => (string) ($settings['empty_text'] ?? __('暂无评论,来做第一个评论的人吧~', 'aksrt')),
|
|
'toolbar' => $toolbar,
|
|
'upload_enabled' => !empty($toolbar['upload_img']),
|
|
'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']),
|
|
'oauth_providers' => class_exists('AKSRT_OAuth')
|
|
? AKSRT_OAuth::get_instance()->get_auth_providers_data()
|
|
: [],
|
|
];
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_apply_hottest_order')) :
|
|
/**
|
|
* Apply hottest-order SQL once for the current comments query.
|
|
*/
|
|
function aksrt_comments_apply_hottest_order(): void {
|
|
static $applied = false;
|
|
if ($applied) {
|
|
return;
|
|
}
|
|
$applied = true;
|
|
|
|
add_filter('comments_clauses', static function ($clauses) {
|
|
global $wpdb;
|
|
$clauses['join'] .= " LEFT JOIN {$wpdb->commentmeta} AS aksrt_cm ON ({$wpdb->comments}.comment_ID = aksrt_cm.comment_id AND aksrt_cm.meta_key = 'aksrt_comment_likes')";
|
|
$clauses['orderby'] = 'CAST(aksrt_cm.meta_value AS UNSIGNED) DESC, ' . $clauses['orderby'];
|
|
return $clauses;
|
|
});
|
|
}
|
|
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'] : [];
|
|
?>
|
|
<div class="comment-signarea text-center box-body radius8">
|
|
<i class="fas fa-lock" aria-hidden="true"></i>
|
|
<span><?php esc_html_e('登录后参与评论', 'aksrt'); ?></span>
|
|
<div class="comment-login-prompt__btns">
|
|
<a class="signin-loader but hollow" href="<?php echo esc_url(function_exists('aksrt_get_login_url') ? aksrt_get_login_url(get_permalink()) : wp_login_url(get_permalink())); ?>"><?php esc_html_e('登录', 'aksrt'); ?></a>
|
|
<?php if (get_option('users_can_register')) : ?>
|
|
<a class="signup-loader but b-theme" href="<?php echo esc_url(function_exists('aksrt_get_register_url') ? aksrt_get_register_url() : wp_registration_url()); ?>"><?php esc_html_e('注册', 'aksrt'); ?></a>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php if (!empty($oauth_providers)) : ?>
|
|
<div class="comment-signarea__oauth">
|
|
<?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 <?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; ?>
|
|
</div>
|
|
<?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;
|
|
$avatar_size = (int) $ctx['avatar_size'];
|
|
$toolbar = is_array($ctx['toolbar'] ?? null) ? $ctx['toolbar'] : [];
|
|
$upload_enabled = !empty($ctx['upload_enabled']);
|
|
?>
|
|
<div id="respond" class="comment-respond mobile-fixed">
|
|
<form id="commentform" class="comment-form" method="post" action="<?php echo esc_url(site_url('/wp-comments-post.php')); ?>">
|
|
<div class="fixed-body">
|
|
<div class="comment-form__inner">
|
|
<div class="comment-form__avatar">
|
|
<?php if ($is_logged_in && $current_user instanceof WP_User) : ?>
|
|
<img src="<?php echo esc_url(get_avatar_url($current_user->ID, ['size' => $avatar_size])); ?>" alt="" width="<?php echo esc_attr((string) $avatar_size); ?>" height="<?php echo esc_attr((string) $avatar_size); ?>" class="avatar-img comt-avatar">
|
|
<?php else : ?>
|
|
<div class="comment-form__avatar-placeholder"><i class="fas fa-user"></i></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="grow1 comt-box">
|
|
<div class="comt-tips" id="comment-reply-info" style="display:none;">
|
|
<span class="comt-tips-left comment-form__reply-text"></span>
|
|
<span class="comt-tips-right"><a href="javascript:;" id="cancel-comment-reply-link" class="comment-form__cancel-reply"><i class="fas fa-times"></i> <?php esc_html_e('取消', 'aksrt'); ?></a></span>
|
|
</div>
|
|
<textarea id="comment" name="comment" class="form-control grin" rows="3" placeholder="<?php echo esc_attr((string) $ctx['box_placeholder']); ?>" required></textarea>
|
|
<div class="comt-ctrl">
|
|
<div class="comment-toolbar" role="toolbar" aria-label="<?php esc_attr_e('评论工具栏', 'aksrt'); ?>">
|
|
<button type="button" class="comment-toolbar__btn"<?php echo empty($toolbar['smilie']) ? ' hidden' : ''; ?> title="<?php esc_attr_e('表情', 'aksrt'); ?>" data-toolbar-action="emoji"><i class="far fa-smile"></i></button>
|
|
<button type="button" class="comment-toolbar__btn"<?php echo empty($toolbar['code']) ? ' hidden' : ''; ?> title="<?php esc_attr_e('插入代码', 'aksrt'); ?>" data-toolbar-action="code"><i class="fas fa-code"></i></button>
|
|
<button type="button" class="comment-toolbar__btn"<?php echo empty($toolbar['image']) ? ' hidden' : ''; ?> title="<?php esc_attr_e('图片', 'aksrt'); ?>" data-toolbar-action="image"><i class="fas fa-image"></i></button>
|
|
<button type="button" class="comment-toolbar__btn"<?php echo $upload_enabled ? '' : ' hidden'; ?> title="<?php esc_attr_e('上传图片', 'aksrt'); ?>" data-toolbar-action="upload-image"><i class="fas fa-cloud-upload-alt"></i></button>
|
|
<button type="button" class="comment-toolbar__btn" title="<?php esc_attr_e('快捷回复', 'aksrt'); ?>" data-toolbar-action="quick-reply"><i class="fas fa-bolt"></i></button>
|
|
</div>
|
|
<div class="comment-form__submit-area">
|
|
<?php if (!$is_logged_in) : ?>
|
|
<input type="text" name="author" class="form-control form-control-sm comment-form__guest-field" placeholder="<?php esc_attr_e('昵称', 'aksrt'); ?>" required>
|
|
<input type="email" name="email" class="form-control form-control-sm comment-form__guest-field" placeholder="<?php esc_attr_e('邮箱', 'aksrt'); ?>" required>
|
|
<?php endif; ?>
|
|
<button type="submit" class="btn btn-primary btn-sm comment-form__submit" id="comment-submit">
|
|
<i class="fas fa-paper-plane" aria-hidden="true"></i>
|
|
<?php echo esc_html((string) $ctx['submit_text']); ?>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<?php if (function_exists('aksrt_is_captcha_enabled_for') && function_exists('aksrt_render_captcha') && aksrt_is_captcha_enabled_for('comment')) : ?>
|
|
<div class="comment-form__captcha">
|
|
<?php aksrt_render_captcha('comment'); ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php comment_id_fields(); ?>
|
|
<?php wp_nonce_field('aksrt_comment_nonce', '_aksrt_comment_nonce'); ?>
|
|
<input type="hidden" name="comment_post_ID" value="<?php echo esc_attr((string) get_the_ID()); ?>">
|
|
</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">
|
|
<ul class="list-inline comment-order-box">
|
|
<li class="<?php echo $order === 'newest' ? 'active' : ''; ?>"><a href="javascript:;" class="comment-orderby" data-order="newest"><?php esc_html_e('最新', 'aksrt'); ?></a></li>
|
|
<li class="<?php echo $order === 'hottest' ? 'active' : ''; ?>"><a href="javascript:;" class="comment-orderby" data-order="hottest"><?php esc_html_e('最热', 'aksrt'); ?></a></li>
|
|
</ul>
|
|
<?php if ($post_author_id > 0) : ?>
|
|
<a href="javascript:;" class="btn-only-author<?php echo $author_only ? ' active' : ''; ?> comment-author-filter" data-author-only="<?php echo $author_only ? '0' : '1'; ?>"><?php esc_html_e('只看作者', 'aksrt'); ?></a>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_render_list')) :
|
|
/**
|
|
* Comment list + pagination.
|
|
*
|
|
* @param array<string,mixed> $ctx Comments context.
|
|
*/
|
|
function aksrt_comments_render_list(array $ctx): void {
|
|
?>
|
|
<div id="postcomments">
|
|
<ol class="commentlist list-unstyled" id="comment-list">
|
|
<?php
|
|
wp_list_comments([
|
|
'style' => 'ol',
|
|
'short_ping' => true,
|
|
'avatar_size' => (int) $ctx['avatar_size'],
|
|
'max_depth' => (int) $ctx['max_depth'],
|
|
'callback' => 'aksrt_comment_callback',
|
|
'reverse_top_level' => !empty($ctx['reverse_comments']),
|
|
'reverse_children' => !empty($ctx['reverse_comments']),
|
|
]);
|
|
?>
|
|
</ol>
|
|
</div>
|
|
<?php
|
|
if (function_exists('aksrt_render_comment_pagination')) {
|
|
aksrt_render_comment_pagination();
|
|
}
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_render_empty')) :
|
|
/**
|
|
* Empty state.
|
|
*
|
|
* @param array<string,mixed> $ctx Comments context.
|
|
*/
|
|
function aksrt_comments_render_empty(array $ctx): void {
|
|
?>
|
|
<div class="comments-empty post_ajax_loader">
|
|
<div class="comments-empty__icon">
|
|
<i class="far fa-comment-dots"></i>
|
|
</div>
|
|
<p class="comments-empty__text"><?php echo esc_html((string) $ctx['empty_text']); ?></p>
|
|
<p class="comments-empty__hint"><?php esc_html_e('成为第一个评论者吧', 'aksrt'); ?></p>
|
|
</div>
|
|
<?php
|
|
}
|
|
endif;
|
|
|
|
if (!function_exists('aksrt_comments_render')) :
|
|
/**
|
|
* Compose the full comments surface.
|
|
*/
|
|
function aksrt_comments_render(): void {
|
|
if (post_password_required()) {
|
|
return;
|
|
}
|
|
|
|
$ctx = aksrt_comments_build_context();
|
|
if (!empty($ctx['is_hottest'])) {
|
|
aksrt_comments_apply_hottest_order();
|
|
}
|
|
|
|
// Keep callback/pagination contracts that still read these query vars.
|
|
set_query_var('aksrt_comment_order', (string) $ctx['order']);
|
|
set_query_var('aksrt_comment_settings', $ctx['settings']);
|
|
|
|
$avatar_size = (int) $ctx['avatar_size'];
|
|
?>
|
|
<div class="theme-box" id="comments" style="<?php echo esc_attr('--aksrt-comment-avatar:' . $avatar_size . 'px;--aksrt-comment-avatar-form:' . max(40, $avatar_size) . 'px;--aksrt-comment-indent:' . $avatar_size . 'px;'); ?>">
|
|
<div class="box-body notop">
|
|
<div class="title-theme">
|
|
<?php echo esc_html((string) $ctx['title_text']); ?>
|
|
<small class="comments-count"><?php echo esc_html(sprintf(__('共 %d 条', 'aksrt'), (int) $ctx['comment_count'])); ?></small>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (comments_open()) : ?>
|
|
<?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; ?>
|
|
<?php endif; ?>
|
|
|
|
<?php if (have_comments()) : ?>
|
|
<?php aksrt_comments_render_filter($ctx); ?>
|
|
<?php aksrt_comments_render_list($ctx); ?>
|
|
<?php elseif (!have_comments() && !post_password_required()) : ?>
|
|
<?php aksrt_comments_render_empty($ctx); ?>
|
|
<?php endif; ?>
|
|
|
|
<?php if (!comments_open() && get_comments_number() && post_type_supports(get_post_type(), 'comments')) : ?>
|
|
<p class="comments-closed"><?php esc_html_e('评论已关闭。', 'aksrt'); ?></p>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php
|
|
}
|
|
endif;
|