fix(forum): accept plate CPT IDs when creating topics

Compose UI and board search already send aksrt_forum_plate post IDs as
board_id, but create_topic still validated aksrt_forum_board term IDs and
never wrote _aksrt_plate_id — so real plates failed with 版块不存在.
Validate/store under the plate model (and fix move_board the same way).
This commit is contained in:
2026-07-17 18:01:24 +08:00
parent 1210556bfd
commit 2ce1b550ff
2 changed files with 75 additions and 15 deletions
+55 -7
View File
@@ -100,9 +100,9 @@ class TopicService {
// §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'));
$board_ok = $this->assert_board($board_id);
if (is_wp_error($board_ok)) {
return $board_ok;
}
if (!isset($this->get_visibility_map()[$visibility])) {
@@ -125,7 +125,7 @@ class TopicService {
return $post_id;
}
wp_set_object_terms($post_id, [$board_id], 'aksrt_forum_board');
$this->attach_topic_to_board((int) $post_id, $board_id);
$clean_tags = array_values(array_filter(array_map('sanitize_text_field', $tags)));
if (count($clean_tags) > 5) {
@@ -198,12 +198,60 @@ class TopicService {
}
// ================================================================
// Topic moderation
// Board / plate attachment helpers
// ================================================================
/**
* Moderate topic.
* Validate board_id as plate CPT post ID when plate is active, else taxonomy term.
*
* @return array<string,mixed>|\WP_Error
* @return true|\WP_Error
*/
private function assert_board(int $board_id, string $error_message = '') {
if ($error_message === '') {
$error_message = __('版块不存在', 'aksrt');
}
if ($board_id <= 0) {
return new \WP_Error('invalid_board', $error_message);
}
if ($this->forum->is_plate_cpt_active()) {
$post = get_post($board_id);
if (!$post || $post->post_type !== 'aksrt_forum_plate' || $post->post_status !== 'publish') {
return new \WP_Error('invalid_board', $error_message);
}
return true;
}
$board = get_term($board_id, 'aksrt_forum_board');
if (!$board || is_wp_error($board)) {
return new \WP_Error('invalid_board', $error_message);
}
return true;
}
/**
* Attach a topic to a board.
* Plate CPT active: store `_aksrt_plate_id` only (native association).
* Otherwise: taxonomy term on aksrt_forum_board.
*/
private function attach_topic_to_board(int $topic_id, int $board_id): void {
if ($topic_id <= 0 || $board_id <= 0) {
return;
}
if ($this->forum->is_plate_cpt_active()) {
update_post_meta($topic_id, '_aksrt_plate_id', $board_id);
return;
}
if (taxonomy_exists('aksrt_forum_board')) {
wp_set_object_terms($topic_id, [$board_id], 'aksrt_forum_board');
}
}
// ================================================================
// Topic moderation
// ================================================================
}
+20 -8
View File
@@ -25,17 +25,29 @@ trait TopicServicePart1 {
switch ($action) {
case 'move_board':
$target_board_id = (int) ($payload['target_board_id'] ?? 0);
$target_board = get_term($target_board_id, 'aksrt_forum_board');
if (!$target_board || is_wp_error($target_board)) {
return new \WP_Error('invalid_board', __('目标版块不存在', 'aksrt'));
$target_ok = $this->assert_board($target_board_id, __('目标版块不存在', 'aksrt'));
if (is_wp_error($target_ok)) {
return $target_ok;
}
$current_board_ids = wp_get_post_terms($topic_id, 'aksrt_forum_board', ['fields' => 'ids']);
wp_set_object_terms($topic_id, [$target_board_id], 'aksrt_forum_board');
foreach ($current_board_ids as $current_board_id) {
$this->forum->sync_board_count((int) $current_board_id);
if ($this->forum->is_plate_cpt_active()) {
$previous_plate_id = (int) $this->forum->get_topic_plate_id($topic_id);
$this->attach_topic_to_board($topic_id, $target_board_id);
if ($previous_plate_id > 0 && $previous_plate_id !== $target_board_id) {
$this->forum->sync_board_count($previous_plate_id);
}
$this->forum->sync_board_count($target_board_id);
} else {
$current_board_ids = wp_get_post_terms($topic_id, 'aksrt_forum_board', ['fields' => 'ids']);
if (is_wp_error($current_board_ids)) {
$current_board_ids = [];
}
$this->attach_topic_to_board($topic_id, $target_board_id);
foreach ($current_board_ids as $current_board_id) {
$this->forum->sync_board_count((int) $current_board_id);
}
$this->forum->sync_board_count($target_board_id);
}
$this->forum->sync_board_count($target_board_id);
break;
case 'visibility':