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|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|WP_Error */ }