ID, '_aksrt_plate_id', true); $sticky = (int) get_post_meta($post->ID, '_aksrt_sticky', true); $locked = (int) get_post_meta($post->ID, '_aksrt_locked', true); $featured = (int) get_post_meta($post->ID, '_aksrt_featured', true); $review = (string) get_post_meta($post->ID, '_aksrt_review_status', true); if ($review === '') { $review = 'approved'; } $bbs_type = (string) (get_post_meta($post->ID, '_aksrt_bbs_type', true) ?: 'standard'); $visibility = sanitize_key((string) (get_post_meta($post->ID, '_aksrt_visibility', true) ?: 'public')); if (!in_array($visibility, self::VISIBILITY, true)) { $visibility = 'public'; } $credits_cost = (int) get_post_meta($post->ID, '_aksrt_credits_cost', true); if ($credits_cost <= 0) { // Legacy dual key. $credits_cost = max(0, (int) get_post_meta($post->ID, '_aksrt_pay_credits', true)); } $pay_price = (float) get_post_meta($post->ID, '_aksrt_pay_price', true); $pay_vip_price = get_post_meta($post->ID, '_aksrt_pay_vip_price', true); $vip_set = ($pay_vip_price !== '' && $pay_vip_price !== null && $pay_vip_price !== false); $vip_price_val = $vip_set ? (float) $pay_vip_price : ''; $pay_hide_part = (int) get_post_meta($post->ID, '_aksrt_pay_hide_part', true) === 1; $view_roles = get_post_meta($post->ID, '_aksrt_visibility_roles', true); if (!is_array($view_roles)) { $view_roles = []; } $view_roles = array_values(array_filter(array_map('sanitize_key', $view_roles))); $wp_roles = $this->wp_role_options(); $plates = get_posts([ 'post_type' => 'aksrt_forum_plate', 'post_status' => 'publish', 'posts_per_page' => 200, 'orderby' => 'title', 'order' => 'ASC', ]); $visibility_labels = [ 'public' => __('公开', 'aksrt'), 'login' => __('登录可见', 'aksrt'), 'comment' => __('评论可见', 'aksrt'), 'role' => __('指定角色', 'aksrt'), 'credits' => __('支付积分后可见', 'aksrt'), 'pay' => __('付费后可见', 'aksrt'), 'moderator' => __('仅版主', 'aksrt'), ]; ?>


post_type !== 'aksrt_forum_topic' || !current_user_can('edit_post', $post_id)) { return; } $plate_id = isset($_POST['aksrt_plate_id']) ? max(0, (int) $_POST['aksrt_plate_id']) : 0; update_post_meta($post_id, '_aksrt_plate_id', $plate_id); $sticky = isset($_POST['aksrt_sticky']) ? max(0, min(3, (int) $_POST['aksrt_sticky'])) : 0; update_post_meta($post_id, '_aksrt_sticky', $sticky); update_post_meta($post_id, '_aksrt_locked', !empty($_POST['aksrt_locked']) ? 1 : 0); update_post_meta($post_id, '_aksrt_featured', !empty($_POST['aksrt_featured']) ? 1 : 0); $review = isset($_POST['aksrt_review_status']) ? sanitize_key((string) wp_unslash($_POST['aksrt_review_status'])) : 'approved'; if (!in_array($review, ['approved', 'pending', 'rejected'], true)) { $review = 'approved'; } update_post_meta($post_id, '_aksrt_review_status', $review); $bbs_type = isset($_POST['aksrt_bbs_type']) ? sanitize_key((string) wp_unslash($_POST['aksrt_bbs_type'])) : 'standard'; if (!in_array($bbs_type, ['standard', 'question'], true)) { $bbs_type = 'standard'; } update_post_meta($post_id, '_aksrt_bbs_type', $bbs_type); $this->save_visibility_meta($post_id); // Keep board taxonomy bridge roughly in sync when plate selected. if ($plate_id > 0 && taxonomy_exists('aksrt_forum_board')) { $slug = 'plate-' . $plate_id; $term = get_term_by('slug', $slug, 'aksrt_forum_board'); if (!$term) { $title = get_the_title($plate_id) ?: $slug; $created = wp_insert_term($title, 'aksrt_forum_board', ['slug' => $slug]); if (!is_wp_error($created) && !empty($created['term_id'])) { $term_id = (int) $created['term_id']; } else { $term_id = 0; } } else { $term_id = (int) $term->term_id; } if ($term_id > 0) { wp_set_object_terms($post_id, [$term_id], 'aksrt_forum_board', false); } } } private function save_visibility_meta(int $post_id): void { $visibility = isset($_POST['aksrt_visibility']) ? sanitize_key((string) wp_unslash($_POST['aksrt_visibility'])) : 'public'; if (!in_array($visibility, self::VISIBILITY, true)) { $visibility = 'public'; } update_post_meta($post_id, '_aksrt_visibility', $visibility); // Rewrite legacy dual allow_view so admin/runtime stay on one contract. $allow_view_map = [ 'public' => 'public', 'login' => 'login', 'comment' => 'login', 'role' => 'public', 'credits' => 'pay', 'pay' => 'pay', 'moderator' => 'moderator', ]; update_post_meta($post_id, '_aksrt_allow_view', $allow_view_map[$visibility] ?? 'public'); // Roles. if ($visibility === 'role') { $roles = $this->sanitize_role_list($_POST['aksrt_visibility_roles'] ?? []); update_post_meta($post_id, '_aksrt_visibility_roles', $roles); } else { delete_post_meta($post_id, '_aksrt_visibility_roles'); } // Credits (canonical + legacy dual-write). if ($visibility === 'credits') { $cost = isset($_POST['aksrt_credits_cost']) ? max(0, (int) wp_unslash($_POST['aksrt_credits_cost'])) : 0; // Accept legacy field name if UI still posts it. if ($cost <= 0 && isset($_POST['aksrt_pay_credits'])) { $cost = max(0, (int) wp_unslash($_POST['aksrt_pay_credits'])); } update_post_meta($post_id, '_aksrt_credits_cost', $cost); update_post_meta($post_id, '_aksrt_pay_credits', $cost); } else { delete_post_meta($post_id, '_aksrt_credits_cost'); delete_post_meta($post_id, '_aksrt_pay_credits'); } // Cash pay. if ($visibility === 'pay') { $price = isset($_POST['aksrt_pay_price']) ? max(0, (float) wp_unslash($_POST['aksrt_pay_price'])) : 0; update_post_meta($post_id, '_aksrt_pay_price', $price); if (isset($_POST['aksrt_pay_vip_price']) && (string) wp_unslash($_POST['aksrt_pay_vip_price']) !== '') { $vip = max(0, (float) wp_unslash($_POST['aksrt_pay_vip_price'])); update_post_meta($post_id, '_aksrt_pay_vip_price', $vip); } else { delete_post_meta($post_id, '_aksrt_pay_vip_price'); } } else { delete_post_meta($post_id, '_aksrt_pay_price'); delete_post_meta($post_id, '_aksrt_pay_vip_price'); } // Partial hide only meaningful for pay/credits; otherwise clear. if (in_array($visibility, ['pay', 'credits'], true)) { update_post_meta($post_id, '_aksrt_pay_hide_part', !empty($_POST['aksrt_pay_hide_part']) ? 1 : 0); } else { delete_post_meta($post_id, '_aksrt_pay_hide_part'); } } /** * @param mixed $raw * @return string[] */ private function sanitize_role_list($raw): array { if (!is_array($raw)) { return []; } $allowed = array_keys($this->wp_role_options()); $out = []; foreach ($raw as $role) { $role = sanitize_key((string) $role); if ($role !== '' && in_array($role, $allowed, true)) { $out[] = $role; } } return array_values(array_unique($out)); } /** * @return array */ private function wp_role_options(): array { if (!function_exists('wp_roles')) { return []; } $roles = wp_roles(); if (!$roles || !is_array($roles->roles)) { return []; } $out = []; foreach ($roles->roles as $key => $data) { $out[sanitize_key((string) $key)] = (string) ($data['name'] ?? $key); } return $out; } }