导入 AKSRT 主题开发源码
This commit is contained in:
1 parent
9681dd3d48
commit
1268a55dd0
595 files changed
+127705
No files matched your search
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/**
|
||||
* Forum topic service.
|
||||
*
|
||||
* Extracted from AKSRT_Forum to isolate topic CRUD, moderation, voting,
|
||||
* content processing, payload building, unlock flow, and status helpers
|
||||
* into a cohesive unit.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class AKSRT_Forum_Topic_Service {
|
||||
use AKSRT_Forum_Topic_Service_Part_1;
|
||||
use AKSRT_Forum_Topic_Service_Part_2;
|
||||
use AKSRT_Forum_Topic_Service_Part_3;
|
||||
use AKSRT_Forum_Topic_Service_Part_4;
|
||||
|
||||
|
||||
private AKSRT_Forum $forum;
|
||||
|
||||
public function __construct(AKSRT_Forum $forum) {
|
||||
$this->forum = $forum;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Topic CRUD
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Update topic content and editable governance metadata.
|
||||
*
|
||||
* @return bool|WP_Error
|
||||
*/
|
||||
public function update_topic(int $topic_id, array $data) {
|
||||
$post = get_post($topic_id);
|
||||
if (!$post || $post->post_type !== 'aksrt_forum_topic') {
|
||||
return new WP_Error('invalid_topic', __('帖子不存在', 'aksrt'));
|
||||
}
|
||||
|
||||
$update = ['ID' => $topic_id];
|
||||
|
||||
if (isset($data['title'])) {
|
||||
$title = sanitize_text_field((string) $data['title']);
|
||||
if ($title === '') {
|
||||
return new WP_Error('empty_title', __('标题不能为空', 'aksrt'));
|
||||
}
|
||||
$update['post_title'] = $title;
|
||||
}
|
||||
|
||||
if (isset($data['content'])) {
|
||||
$content = wp_kses_post((string) $data['content']);
|
||||
if ($content === '') {
|
||||
return new WP_Error('empty_content', __('内容不能为空', 'aksrt'));
|
||||
}
|
||||
$update['post_content'] = $content;
|
||||
}
|
||||
|
||||
if (isset($data['excerpt'])) {
|
||||
$update['post_excerpt'] = sanitize_textarea_field((string) $data['excerpt']);
|
||||
}
|
||||
|
||||
$result = wp_update_post($update, true);
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if (isset($data['tags']) && is_array($data['tags'])) {
|
||||
$tags = array_values(array_filter(array_map('sanitize_text_field', $data['tags'])));
|
||||
wp_set_object_terms($topic_id, $tags, 'aksrt_forum_tag');
|
||||
}
|
||||
|
||||
$this->save_topic_governance_meta($topic_id, $data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create topic.
|
||||
*
|
||||
* @return array<string,mixed>|WP_Error
|
||||
*/
|
||||
public function create_topic(int $user_id, array $data) {
|
||||
if ($user_id <= 0) {
|
||||
return new WP_Error('not_logged_in', __('请先登录', 'aksrt'));
|
||||
}
|
||||
|
||||
$board_id = (int) ($data['board_id'] ?? 0);
|
||||
$title = sanitize_text_field((string) ($data['title'] ?? ''));
|
||||
$content = wp_kses_post((string) ($data['content'] ?? ''));
|
||||
$visibility = sanitize_key((string) ($data['visibility'] ?? AKSRT_Forum::VISIBILITY_PUBLIC));
|
||||
$special_topic = sanitize_text_field((string) ($data['special_topic'] ?? ''));
|
||||
$tags = is_array($data['tags'] ?? null) ? $data['tags'] : [];
|
||||
$bbs_type = sanitize_key((string) ($data['bbs_type'] ?? AKSRT_Forum::BBS_TYPE_STANDARD));
|
||||
if (!in_array($bbs_type, [AKSRT_Forum::BBS_TYPE_STANDARD, AKSRT_Forum::BBS_TYPE_QUESTION], true)) {
|
||||
$bbs_type = AKSRT_Forum::BBS_TYPE_STANDARD;
|
||||
}
|
||||
|
||||
if ($board_id <= 0 || $title === '' || $content === '') {
|
||||
return new WP_Error('invalid_payload', __('请填写所有必填项', 'aksrt'));
|
||||
}
|
||||
|
||||
// §7.3: Strip unauthorized media from content based on compose capabilities
|
||||
$content = $this->sanitize_topic_content($user_id, $content);
|
||||
|
||||
$board = get_term($board_id, 'aksrt_forum_board');
|
||||
if (!$board || is_wp_error($board)) {
|
||||
return new WP_Error('invalid_board', __('版块不存在', 'aksrt'));
|
||||
}
|
||||
|
||||
if (!isset($this->get_visibility_map()[$visibility])) {
|
||||
$visibility = AKSRT_Forum::VISIBILITY_PUBLIC;
|
||||
}
|
||||
|
||||
$can_publish = $this->can_user_publish_directly($user_id, $board_id);
|
||||
$post_status = $can_publish ? 'publish' : 'pending';
|
||||
$review_status = $can_publish ? AKSRT_Forum::REVIEW_APPROVED : AKSRT_Forum::REVIEW_PENDING;
|
||||
|
||||
$post_id = wp_insert_post([
|
||||
'post_title' => $title,
|
||||
'post_content' => $content,
|
||||
'post_status' => $post_status,
|
||||
'post_author' => $user_id,
|
||||
'post_type' => 'aksrt_forum_topic',
|
||||
], true);
|
||||
|
||||
if (is_wp_error($post_id)) {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
wp_set_object_terms($post_id, [$board_id], 'aksrt_forum_board');
|
||||
|
||||
$clean_tags = array_values(array_filter(array_map('sanitize_text_field', $tags)));
|
||||
if (count($clean_tags) > 5) {
|
||||
$clean_tags = array_slice($clean_tags, 0, 5);
|
||||
}
|
||||
if (!empty($clean_tags)) {
|
||||
wp_set_object_terms($post_id, $clean_tags, 'aksrt_forum_tag');
|
||||
}
|
||||
|
||||
$topic_cat = sanitize_text_field((string) ($data['topic_cat'] ?? ''));
|
||||
if ($topic_cat !== '' && taxonomy_exists('aksrt_forum_topic_cat')) {
|
||||
wp_set_object_terms($post_id, [$topic_cat], 'aksrt_forum_topic_cat');
|
||||
}
|
||||
|
||||
update_post_meta($post_id, '_aksrt_visibility', $visibility);
|
||||
update_post_meta($post_id, '_aksrt_review_status', $review_status);
|
||||
|
||||
if ($visibility === AKSRT_Forum::VISIBILITY_CREDITS) {
|
||||
$credits_cost = max(0, (int) ($data['credits_cost'] ?? 0));
|
||||
update_post_meta($post_id, '_aksrt_credits_cost', $credits_cost);
|
||||
}
|
||||
if ($visibility === AKSRT_Forum::VISIBILITY_PAY) {
|
||||
$pay_price = sanitize_text_field((string) ($data['pay_price'] ?? ''));
|
||||
update_post_meta($post_id, '_aksrt_pay_price', $pay_price);
|
||||
}
|
||||
if ($visibility === AKSRT_Forum::VISIBILITY_ROLE) {
|
||||
$roles = isset($data['visibility_roles']) && is_array($data['visibility_roles'])
|
||||
? array_map('sanitize_key', $data['visibility_roles']) : [];
|
||||
update_post_meta($post_id, '_aksrt_visibility_roles', $roles);
|
||||
}
|
||||
|
||||
update_post_meta($post_id, '_aksrt_special_topic', $special_topic);
|
||||
// 置顶分级 0~3(§7.3):新建主题默认不置顶。
|
||||
update_post_meta($post_id, '_aksrt_sticky', AKSRT_Forum::STICKY_NONE);
|
||||
update_post_meta($post_id, '_aksrt_featured', '0');
|
||||
update_post_meta($post_id, '_aksrt_locked', '0');
|
||||
update_post_meta($post_id, '_aksrt_views', 0);
|
||||
update_post_meta($post_id, '_aksrt_bbs_type', $bbs_type);
|
||||
if ($bbs_type === AKSRT_Forum::BBS_TYPE_QUESTION) {
|
||||
update_post_meta($post_id, '_aksrt_question_status', AKSRT_Forum::QUESTION_UNSOLVED);
|
||||
}
|
||||
|
||||
$this->save_cover_meta($post_id, $data);
|
||||
|
||||
$vote_meta = $this->prepare_vote_meta($data);
|
||||
$this->save_vote_meta($post_id, $vote_meta);
|
||||
|
||||
if ($post_status === 'publish') {
|
||||
$this->forum->sync_board_count($board_id);
|
||||
}
|
||||
|
||||
if (class_exists('AKSRT_Credits_Earn') && $post_status === 'publish') {
|
||||
do_action('aksrt_forum_topic_created', $user_id, $post_id);
|
||||
}
|
||||
|
||||
if ($post_status === 'pending') {
|
||||
$this->forum->notify_topic_pending($post_id, $user_id);
|
||||
}
|
||||
|
||||
return [
|
||||
'post_id' => $post_id,
|
||||
'message' => $post_status === 'publish'
|
||||
? __('主题已发布', 'aksrt')
|
||||
: __('主题已提交审核,审核通过后对外展示', 'aksrt'),
|
||||
'redirect' => $post_status === 'publish'
|
||||
? get_permalink($post_id)
|
||||
: add_query_arg('compose_status', 'pending', home_url('/forums/')),
|
||||
];
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Topic moderation
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Moderate topic.
|
||||
*
|
||||
* @return array<string,mixed>|WP_Error
|
||||
*/
|
||||
}
|
||||
Reference in new issue
Block a user