feat(comments): full 1:1 zibll comment kernel for posts, forum, shop
Extract shared comment helpers (content/item/form/geo/actions), port GIF [g=] smilies + FixedInput/moveForm UX, wire close_comments/city/quick settings, REST comment get, and align product review chrome with zibll.
This commit is contained in:
@@ -265,6 +265,14 @@ class SchemaPostList {
|
||||
['key' => 'comment_like_s', 'label' => '评论点赞', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'comment_quick_s', 'label' => '快捷回复', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'comment_city_s', 'label' => '评论城市', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'comment_city_type', 'label' => '城市显示格式', 'type' => 'radio', 'default' => 'province_city', 'options' => [
|
||||
['label' => '省份+城市', 'value' => 'province_city'],
|
||||
['label' => '仅省份', 'value' => 'province'],
|
||||
['label' => '国家+省份', 'value' => 'country_province'],
|
||||
]],
|
||||
['key' => 'comment_quick_often', 'label' => '快捷回复短语', 'type' => 'textarea', 'default' => "不错,学习了
|
||||
感谢分享
|
||||
期待更新"],
|
||||
['key' => 'comment_author_tag', 'label' => '作者标签', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'comment_corderby', 'label' => '评论排序切换', 'type' => 'switch', 'default' => true, 'description' => '前台显示最新/最早/最热切换按钮'],
|
||||
]],
|
||||
|
||||
@@ -92,6 +92,51 @@ class CommentActions {
|
||||
'active' => ['required' => false, 'type' => 'boolean'],
|
||||
],
|
||||
]);
|
||||
|
||||
register_rest_route('aksrt/v1', '/comment/get', [
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => [$this, 'get_comment'],
|
||||
'permission_callback' => [$this, 'check_get_permission'],
|
||||
'args' => [
|
||||
'comment_id' => ['required' => true, 'type' => 'integer', 'sanitize_callback' => 'absint'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Permission: can load raw content for edit?
|
||||
*/
|
||||
public function check_get_permission(\WP_REST_Request $request): bool {
|
||||
$comment_id = (int) $request->get_param('comment_id');
|
||||
if ($comment_id <= 0 || !is_user_logged_in()) {
|
||||
return false;
|
||||
}
|
||||
$perms = $this->permissions($comment_id);
|
||||
return !empty($perms['can_edit']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return raw comment content for moveForm edit.
|
||||
*/
|
||||
public function get_comment(\WP_REST_Request $request): \WP_REST_Response {
|
||||
$comment_id = (int) $request->get_param('comment_id');
|
||||
$comment = get_comment($comment_id);
|
||||
if (!$comment) {
|
||||
return new \WP_REST_Response([
|
||||
'success' => false,
|
||||
'code' => 'comment_not_found',
|
||||
'message' => __('评论不存在。', 'aksrt'),
|
||||
], 404);
|
||||
}
|
||||
return new \WP_REST_Response([
|
||||
'success' => true,
|
||||
'content' => (string) $comment->comment_content,
|
||||
'data' => [
|
||||
'content' => (string) $comment->comment_content,
|
||||
'comment_id' => $comment_id,
|
||||
'parent' => (int) $comment->comment_parent,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,6 +238,13 @@ class CommentActions {
|
||||
$params = [];
|
||||
}
|
||||
|
||||
$edit_id = absint($params['edit_comment_ID'] ?? $params['edit_comment_id'] ?? 0);
|
||||
if ($edit_id > 0) {
|
||||
$request->set_param('comment_id', $edit_id);
|
||||
$request->set_param('content', (string) ($params['comment'] ?? $params['content'] ?? ''));
|
||||
return $this->edit_comment($request);
|
||||
}
|
||||
|
||||
$post_id = absint($params['comment_post_ID'] ?? $params['post_id'] ?? 0);
|
||||
$content = isset($params['comment']) ? (string) $params['comment'] : '';
|
||||
$parent = absint($params['comment_parent'] ?? 0);
|
||||
|
||||
@@ -226,7 +226,22 @@ trait ScriptsPart1b {
|
||||
// Keep aggregator handle for any third-party deps that target it.
|
||||
$enqueue_module('single-post');
|
||||
$enqueue_module('post-card'); // 相关推荐使用 post-card 局部样式
|
||||
$enqueue_module('comments');
|
||||
// Comments pack (zibll 1:1 discrete files).
|
||||
$comment_parts = ['comments/shell', 'comments/mobile-item'];
|
||||
$comment_dep = $deps[0] ?? $core_dep;
|
||||
foreach ($comment_parts as $part) {
|
||||
$path = get_template_directory() . '/assets/css/frontend/' . $part . '.css';
|
||||
if (!file_exists($path)) {
|
||||
continue;
|
||||
}
|
||||
wp_enqueue_style(
|
||||
'aksrt-' . str_replace('/', '-', $part),
|
||||
$base_uri . '/assets/css/frontend/' . $part . '.css',
|
||||
is_string($comment_dep) ? [$comment_dep] : (array) $deps,
|
||||
filemtime($path) ?: $version
|
||||
);
|
||||
}
|
||||
$enqueue_module('comments'); // aggregator handle for third-party deps
|
||||
$enqueue_module('widgets');
|
||||
$enqueue_module('sidebar');
|
||||
$enqueue_module('breadcrumb');
|
||||
|
||||
@@ -116,6 +116,8 @@ trait ScriptsPart1c {
|
||||
'aksrt-core-slider' => 'slider.js',
|
||||
'aksrt-core-article' => 'article.js',
|
||||
'aksrt-core-comments' => 'comments.js',
|
||||
'aksrt-core-comment-fixed' => 'comment-fixed-input.js',
|
||||
'aksrt-core-comment-move' => 'comment-move-form.js',
|
||||
'aksrt-core-pagination' => 'pagination.js',
|
||||
'aksrt-core-archive' => 'archive.js',
|
||||
'aksrt-core-footer-tabbar' => 'footer-tabbar.js',
|
||||
@@ -424,28 +426,38 @@ trait ScriptsPart1c {
|
||||
}
|
||||
|
||||
|
||||
// Comment toolbar (emoji, code, bold, Ctrl+Enter) — only when the form is open.
|
||||
if (is_singular() && comments_open()) {
|
||||
// Comment toolbar (smilie/code/image/quick shortcodes) — post form or forum topic reply.
|
||||
$load_comment_tools = (is_singular() && comments_open())
|
||||
|| (is_singular('aksrt_forum_topic') || is_singular('forum_topic'));
|
||||
if ($load_comment_tools) {
|
||||
$comment_tools_path = get_template_directory() . '/assets/js/comment-tools.js';
|
||||
wp_enqueue_script(
|
||||
'aksrt-comment-tools',
|
||||
$base_uri . '/assets/js/comment-tools.js',
|
||||
['aksrt-script'],
|
||||
['aksrt-script', 'aksrt-core-comment-fixed', 'aksrt-core-comment-move'],
|
||||
file_exists($comment_tools_path) ? (string) filemtime($comment_tools_path) : $version,
|
||||
true
|
||||
);
|
||||
$comment_tools_css = get_template_directory() . '/assets/css/frontend/comment-tools.css';
|
||||
if (file_exists($comment_tools_css)) {
|
||||
wp_enqueue_style(
|
||||
'aksrt-comment-tools',
|
||||
$base_uri . '/assets/css/frontend/comment-tools.css',
|
||||
['aksrt-comments'],
|
||||
(string) filemtime($comment_tools_css)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Comment actions client (like / edit / delete / moderate / pin) — load
|
||||
// wherever comments can exist, including closed-comment posts. Submission
|
||||
// itself is handled by main.js initCommentSystem().
|
||||
// Comment actions client (like / edit / delete / moderate / pin).
|
||||
// Submit path lives in assets/js/core/comments.js (REST).
|
||||
if (is_singular() && (comments_open() || (int) get_comments_number() > 0)) {
|
||||
$comment_ajax_path = get_template_directory() . '/assets/js/comment-ajax.js';
|
||||
if (file_exists($comment_ajax_path)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-comment-ajax',
|
||||
$base_uri . '/assets/js/comment-ajax.js',
|
||||
['aksrt-script'],
|
||||
['aksrt-script', 'aksrt-core-comments'],
|
||||
(string) filemtime($comment_ajax_path),
|
||||
true
|
||||
);
|
||||
@@ -534,6 +546,9 @@ trait ScriptsPart1c {
|
||||
'commentUploadUrl' => esc_url_raw(rest_url('aksrt/v1/comment/upload-image')),
|
||||
'commentUploadMaxSize' => 2 * 1024 * 1024,
|
||||
'commentIasMax' => class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_comment_display_settings()['paging_ajax_ias_max'] : 3,
|
||||
'commentQuickPhrases' => class_exists('\AKSRT\Settings\Settings') ? (\AKSRT\Settings\Settings::get_comment_display_settings()['quick_phrases'] ?? []) : [],
|
||||
'commentSmiliesBase' => function_exists('aksrt_comment_smilies_base_uri') ? aksrt_comment_smilies_base_uri() : (trailingslashit(get_template_directory_uri()) . 'assets/img/smilies/'),
|
||||
'restUrl' => esc_url_raw(rest_url('aksrt/v1')),
|
||||
'stickyEnabled' => class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_post_list_style_settings()['sticky_enabled'] : true,
|
||||
'stickyPages' => class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_post_list_style_settings()['sticky_pages'] : ['home', 'cat'],
|
||||
'badgeShow' => class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_post_list_style_settings()['badge_show'] : true,
|
||||
|
||||
@@ -465,9 +465,48 @@ class PostDisplay {
|
||||
'submit_text' => $submit_text !== '' ? $submit_text : __('提交评论', 'aksrt'),
|
||||
'box_placeholder' => $box_placeholder !== '' ? $box_placeholder : __('说点什么吧...', 'aksrt'),
|
||||
'title' => $title !== '' ? $title : __('评论', 'aksrt'),
|
||||
// Extended zibll-parity settings.
|
||||
'close_comments' => !empty($settings['comment_close_comments']),
|
||||
'hot_threshold' => max(1, min(999, (int) ($settings['comment_hot_threshold'] ?? 10))),
|
||||
'quick_s' => !isset($settings['comment_quick_s']) || !empty($settings['comment_quick_s']),
|
||||
'quick_phrases' => self::parse_comment_quick_phrases((string) ($settings['comment_quick_often'] ?? '')),
|
||||
'city_s' => !isset($settings['comment_city_s']) || !empty($settings['comment_city_s']),
|
||||
'city_type' => self::normalize_comment_city_type((string) ($settings['comment_city_type'] ?? 'province_city')),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int,string>
|
||||
*/
|
||||
private static function parse_comment_quick_phrases(string $raw): array {
|
||||
if (trim($raw) === '') {
|
||||
$raw = "不错,学习了\n感谢分享\n期待更新";
|
||||
}
|
||||
$lines = preg_split('/\r\n|\r|\n/', $raw) ?: [];
|
||||
$out = [];
|
||||
foreach ($lines as $line) {
|
||||
$line = trim((string) $line);
|
||||
if ($line !== '') {
|
||||
$out[] = $line;
|
||||
}
|
||||
}
|
||||
return array_values(array_unique($out));
|
||||
}
|
||||
|
||||
private static function normalize_comment_city_type(string $type): string {
|
||||
$type = sanitize_key($type);
|
||||
// Map legacy zibll pro/city labels.
|
||||
if ($type === 'pro') {
|
||||
return 'province';
|
||||
}
|
||||
if ($type === 'city') {
|
||||
return 'province_city';
|
||||
}
|
||||
return in_array($type, ['province_city', 'province', 'country_province'], true)
|
||||
? $type
|
||||
: 'province_city';
|
||||
}
|
||||
|
||||
|
||||
public static function apply_list_orderby($query): void {
|
||||
if (is_admin() || !($query instanceof \WP_Query) || !$query->is_main_query()) {
|
||||
|
||||
Reference in New Issue
Block a user