From e0279e1a23f9d684d4480436e796fad9daf4d22b Mon Sep 17 00:00:00 2001
From: unknown
Date: Wed, 15 Jul 2026 02:22:41 +0800
Subject: [PATCH 1/2] feat(admin): topic governance list columns and native
charge-card batching
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add native aksrt_forum_topic list filters/columns/bulk/quick-edit for
sticky/lock/review/plate. Replace SPA charge-card batch link with an
inline batch generator on the 支付中心卡密 page. No build artifacts.
---
functions.php | 5 +
inc/bootstrap.php | 1 +
.../native/class-aksrt-admin-pay-menus.php | 77 +++-
.../forum/class-aksrt-topic-admin-list.php | 409 ++++++++++++++++++
4 files changed, 491 insertions(+), 1 deletion(-)
create mode 100644 inc/classes/forum/class-aksrt-topic-admin-list.php
diff --git a/functions.php b/functions.php
index f2bffc70..36ac10c3 100644
--- a/functions.php
+++ b/functions.php
@@ -307,6 +307,11 @@ if (is_admin() && class_exists('AKSRT_Product_Variants_Meta_Box')) {
if (is_admin() && class_exists('AKSRT_Plate_Meta_Box')) {
AKSRT_Plate_Meta_Box::get_instance()->init();
}
+// 论坛帖子原生列表治理列/筛选/批量
+if (is_admin() && class_exists('AKSRT_Topic_Admin_List')) {
+ AKSRT_Topic_Admin_List::get_instance()->init();
+}
+
// 商品评价/评分系统
diff --git a/inc/bootstrap.php b/inc/bootstrap.php
index 0cb88453..6f09a3ec 100644
--- a/inc/bootstrap.php
+++ b/inc/bootstrap.php
@@ -323,6 +323,7 @@ require_once AKSRT_DIR . '/inc/classes/shop/class-aksrt-shop-product-service.php
require_once AKSRT_DIR . '/inc/classes/shop/class-aksrt-product-meta-box.php';
require_once AKSRT_DIR . '/inc/classes/shop/class-aksrt-product-variants-meta-box.php';
require_once AKSRT_DIR . '/inc/classes/forum/class-aksrt-plate-meta-box.php';
+require_once AKSRT_DIR . '/inc/classes/forum/class-aksrt-topic-admin-list.php';
require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-1.php';
require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-2.php';
require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-3.php';
diff --git a/inc/classes/admin/native/class-aksrt-admin-pay-menus.php b/inc/classes/admin/native/class-aksrt-admin-pay-menus.php
index e0fe26c4..16a9cf10 100644
--- a/inc/classes/admin/native/class-aksrt-admin-pay-menus.php
+++ b/inc/classes/admin/native/class-aksrt-admin-pay-menus.php
@@ -33,6 +33,7 @@ class AKSRT_Admin_Pay_Menus {
add_action('admin_post_aksrt_pay_update_order_status', [$this, 'handle_update_order_status']);
add_action('admin_post_aksrt_pay_update_withdrawal', [$this, 'handle_update_withdrawal']);
add_action('admin_post_aksrt_pay_disable_charge_card', [$this, 'handle_disable_charge_card']);
+ add_action('admin_post_aksrt_pay_batch_charge_cards', [$this, 'handle_batch_charge_cards']);
add_action('admin_post_aksrt_pay_update_shipping', [$this, 'handle_update_shipping']);
add_action('admin_post_aksrt_pay_update_after_sale', [$this, 'handle_update_after_sale']);
add_action('admin_post_aksrt_pay_create_coupon', [$this, 'handle_create_coupon']);
@@ -197,6 +198,8 @@ class AKSRT_Admin_Pay_Menus {
'withdraw_failed' => __('提现状态更新失败。', 'aksrt'),
'card_disabled' => __('充值卡已禁用。', 'aksrt'),
'card_failed' => __('充值卡禁用失败。', 'aksrt'),
+ 'card_batch_ok' => __('卡密批量生成完成。', 'aksrt'),
+ 'card_batch_failed' => __('卡密批量生成失败。', 'aksrt'),
'shipping_updated' => __('物流状态已更新。', 'aksrt'),
'shipping_failed' => __('物流状态更新失败。', 'aksrt'),
'after_sale_updated' => __('售后状态已更新。', 'aksrt'),
@@ -592,6 +595,34 @@ class AKSRT_Admin_Pay_Menus {
(int) ($stats['used'] ?? 0)
)) . '
';
+ echo '' . esc_html__('批量生成卡密', 'aksrt') . '
';
+ echo '';
+
+ if (!empty($_GET['aksrt_generated'])) {
+ $generated = (int) $_GET['aksrt_generated'];
+ echo '' . esc_html(sprintf(
+ /* translators: %d count */
+ __('成功生成 %d 张卡密。', 'aksrt'),
+ $generated
+ )) . '
';
+ }
+
echo '';
$result = $svc->get_list([
@@ -720,6 +751,50 @@ class AKSRT_Admin_Pay_Menus {
exit;
}
+ public function handle_batch_charge_cards(): void {
+ if (!current_user_can(self::CAPABILITY)) {
+ wp_die(esc_html__('权限不足', 'aksrt'));
+ }
+ check_admin_referer('aksrt_pay_batch_charge_cards');
+
+ if (!class_exists('AKSRT_Charge_Card')) {
+ wp_safe_redirect($this->page_url('aksrt_charge_cards', ['aksrt_pay_msg' => 'card_batch_failed']));
+ exit;
+ }
+
+ $type = isset($_POST['type']) ? sanitize_key((string) wp_unslash($_POST['type'])) : 'balance';
+ $count = isset($_POST['count']) ? (int) $_POST['count'] : 10;
+ $length = isset($_POST['length']) ? (int) $_POST['length'] : 16;
+ $prefix = isset($_POST['prefix']) ? sanitize_text_field((string) wp_unslash($_POST['prefix'])) : '';
+ $amount = isset($_POST['amount']) ? (float) wp_unslash($_POST['amount']) : 0;
+ $note = isset($_POST['note']) ? sanitize_textarea_field((string) wp_unslash($_POST['note'])) : '';
+ $level = isset($_POST['vip_level']) ? max(1, min(2, (int) $_POST['vip_level'])) : 1;
+ $days = isset($_POST['vip_days']) ? max(1, (int) $_POST['vip_days']) : 30;
+
+ if ($type === 'points') {
+ $type = 'credits';
+ }
+
+ $meta = [];
+ if ($type === 'balance') {
+ $meta['amount'] = max(0, $amount);
+ } elseif ($type === 'credits') {
+ $meta['points'] = max(0, (int) $amount);
+ } elseif ($type === 'vip') {
+ $meta['level'] = $level;
+ $meta['days'] = $days;
+ }
+
+ $codes = AKSRT_Charge_Card::get_instance()->batch_create($type, $meta, $count, $length, $prefix, '', $note);
+ $ok = !empty($codes);
+
+ wp_safe_redirect($this->page_url('aksrt_charge_cards', [
+ 'aksrt_pay_msg' => $ok ? 'card_batch_ok' : 'card_batch_failed',
+ 'aksrt_generated' => count($codes),
+ ]));
+ exit;
+ }
+
/* ------------------------------------------------------------------
* Shipping
* ----------------------------------------------------------------*/
diff --git a/inc/classes/forum/class-aksrt-topic-admin-list.php b/inc/classes/forum/class-aksrt-topic-admin-list.php
new file mode 100644
index 00000000..f0d584f1
--- /dev/null
+++ b/inc/classes/forum/class-aksrt-topic-admin-list.php
@@ -0,0 +1,409 @@
+ $label) {
+ $new[$key] = $label;
+ if ($key === 'title') {
+ $new['aksrt_plate'] = __('版块', 'aksrt');
+ $new['aksrt_sticky'] = __('置顶', 'aksrt');
+ $new['aksrt_locked'] = __('锁定', 'aksrt');
+ $new['aksrt_review'] = __('审核', 'aksrt');
+ $new['aksrt_bbs_type']= __('类型', 'aksrt');
+ $new['aksrt_views'] = __('阅读', 'aksrt');
+ }
+ }
+ return $new;
+ }
+
+ public function sortable_columns(array $columns): array {
+ $columns['aksrt_sticky'] = 'aksrt_sticky';
+ $columns['aksrt_views'] = 'aksrt_views';
+ return $columns;
+ }
+
+ public function render_column(string $column, int $post_id): void {
+ switch ($column) {
+ case 'aksrt_plate':
+ $plate_id = (int) get_post_meta($post_id, '_aksrt_plate_id', true);
+ if ($plate_id > 0) {
+ $plate = get_post($plate_id);
+ echo $plate ? esc_html(get_the_title($plate)) : esc_html('#' . $plate_id);
+ } else {
+ // fallback board taxonomy
+ $terms = get_the_terms($post_id, 'aksrt_forum_board');
+ if (is_array($terms) && $terms) {
+ echo esc_html($terms[0]->name);
+ } else {
+ echo '—';
+ }
+ }
+ break;
+
+ case 'aksrt_sticky':
+ $sticky = (int) get_post_meta($post_id, '_aksrt_sticky', true);
+ $map = [
+ 0 => __('否', 'aksrt'),
+ 1 => __('版块', 'aksrt'),
+ 2 => __('超级', 'aksrt'),
+ 3 => __('全局', 'aksrt'),
+ ];
+ echo esc_html($map[$sticky] ?? (string) $sticky);
+ echo '';
+ break;
+
+ case 'aksrt_locked':
+ $locked = (int) get_post_meta($post_id, '_aksrt_locked', true);
+ echo $locked ? esc_html__('是', 'aksrt') : esc_html__('否', 'aksrt');
+ break;
+
+ case 'aksrt_review':
+ $status = (string) get_post_meta($post_id, '_aksrt_review_status', true);
+ if ($status === '') {
+ $status = 'approved';
+ }
+ $map = [
+ 'approved' => __('已通过', 'aksrt'),
+ 'pending' => __('待审核', 'aksrt'),
+ 'rejected' => __('已拒绝', 'aksrt'),
+ ];
+ echo esc_html($map[$status] ?? $status);
+ break;
+
+ case 'aksrt_bbs_type':
+ $type = (string) (get_post_meta($post_id, '_aksrt_bbs_type', true) ?: 'standard');
+ echo esc_html($type === 'question' ? __('提问', 'aksrt') : __('标准', 'aksrt'));
+ break;
+
+ case 'aksrt_views':
+ echo esc_html((string) (int) get_post_meta($post_id, '_aksrt_views', true));
+ break;
+ }
+ }
+
+ public function filters(string $post_type): void {
+ if ($post_type !== 'aksrt_forum_topic') {
+ return;
+ }
+
+ $sticky = isset($_GET['aksrt_sticky']) ? sanitize_key((string) wp_unslash($_GET['aksrt_sticky'])) : '';
+ $locked = isset($_GET['aksrt_locked']) ? sanitize_key((string) wp_unslash($_GET['aksrt_locked'])) : '';
+ $review = isset($_GET['aksrt_review']) ? sanitize_key((string) wp_unslash($_GET['aksrt_review'])) : '';
+ $plate = isset($_GET['aksrt_plate']) ? (int) $_GET['aksrt_plate'] : 0;
+
+ echo ' ';
+
+ echo ' ';
+
+ echo ' ';
+
+ $plates = get_posts([
+ 'post_type' => 'aksrt_forum_plate',
+ 'post_status' => 'publish',
+ 'posts_per_page' => 200,
+ 'orderby' => 'title',
+ 'order' => 'ASC',
+ ]);
+ if ($plates) {
+ echo ' ';
+ }
+ }
+
+ public function apply_filters(WP_Query $query): void {
+ if (!is_admin() || !$query->is_main_query()) {
+ return;
+ }
+ $post_type = $query->get('post_type');
+ if ($post_type !== 'aksrt_forum_topic') {
+ return;
+ }
+
+ $meta_query = (array) $query->get('meta_query');
+
+ if (isset($_GET['aksrt_sticky']) && $_GET['aksrt_sticky'] !== '') {
+ $meta_query[] = [
+ 'key' => '_aksrt_sticky',
+ 'value' => (int) $_GET['aksrt_sticky'],
+ ];
+ }
+ if (isset($_GET['aksrt_locked']) && $_GET['aksrt_locked'] !== '') {
+ $meta_query[] = [
+ 'key' => '_aksrt_locked',
+ 'value' => (int) $_GET['aksrt_locked'],
+ ];
+ }
+ if (!empty($_GET['aksrt_review'])) {
+ $review = sanitize_key((string) wp_unslash($_GET['aksrt_review']));
+ if ($review === 'approved') {
+ $meta_query[] = [
+ 'relation' => 'OR',
+ [
+ 'key' => '_aksrt_review_status',
+ 'value' => 'approved',
+ ],
+ [
+ 'key' => '_aksrt_review_status',
+ 'compare' => 'NOT EXISTS',
+ ],
+ [
+ 'key' => '_aksrt_review_status',
+ 'value' => '',
+ ],
+ ];
+ } else {
+ $meta_query[] = [
+ 'key' => '_aksrt_review_status',
+ 'value' => $review,
+ ];
+ }
+ }
+ if (!empty($_GET['aksrt_plate'])) {
+ $meta_query[] = [
+ 'key' => '_aksrt_plate_id',
+ 'value' => (int) $_GET['aksrt_plate'],
+ ];
+ }
+
+ if ($meta_query) {
+ $query->set('meta_query', $meta_query);
+ }
+
+ $orderby = $query->get('orderby');
+ if ($orderby === 'aksrt_sticky') {
+ $query->set('meta_key', '_aksrt_sticky');
+ $query->set('orderby', 'meta_value_num');
+ } elseif ($orderby === 'aksrt_views') {
+ $query->set('meta_key', '_aksrt_views');
+ $query->set('orderby', 'meta_value_num');
+ }
+ }
+
+ public function bulk_actions(array $actions): array {
+ $actions['aksrt_sticky_1'] = __('设为版块置顶', 'aksrt');
+ $actions['aksrt_sticky_0'] = __('取消置顶', 'aksrt');
+ $actions['aksrt_lock'] = __('锁定', 'aksrt');
+ $actions['aksrt_unlock'] = __('解锁', 'aksrt');
+ $actions['aksrt_approve'] = __('审核通过', 'aksrt');
+ $actions['aksrt_reject'] = __('审核拒绝', 'aksrt');
+ return $actions;
+ }
+
+ public function handle_bulk_actions(string $redirect_to, string $action, array $post_ids): string {
+ $count = 0;
+ foreach ($post_ids as $post_id) {
+ $post_id = (int) $post_id;
+ if ($post_id <= 0 || get_post_type($post_id) !== 'aksrt_forum_topic') {
+ continue;
+ }
+ switch ($action) {
+ case 'aksrt_sticky_1':
+ update_post_meta($post_id, '_aksrt_sticky', 1);
+ $count++;
+ break;
+ case 'aksrt_sticky_0':
+ update_post_meta($post_id, '_aksrt_sticky', 0);
+ $count++;
+ break;
+ case 'aksrt_lock':
+ update_post_meta($post_id, '_aksrt_locked', 1);
+ $count++;
+ break;
+ case 'aksrt_unlock':
+ update_post_meta($post_id, '_aksrt_locked', 0);
+ $count++;
+ break;
+ case 'aksrt_approve':
+ update_post_meta($post_id, '_aksrt_review_status', 'approved');
+ $count++;
+ break;
+ case 'aksrt_reject':
+ update_post_meta($post_id, '_aksrt_review_status', 'rejected');
+ $count++;
+ break;
+ }
+ }
+
+ return add_query_arg('aksrt_topic_bulk', $count, $redirect_to);
+ }
+
+ public function bulk_notices(): void {
+ if (empty($_GET['aksrt_topic_bulk'])) {
+ return;
+ }
+ $count = (int) $_GET['aksrt_topic_bulk'];
+ echo '' . esc_html(sprintf(
+ /* translators: %d count */
+ __('已更新 %d 个帖子。', 'aksrt'),
+ $count
+ )) . '
';
+ }
+
+ public function quick_edit_box(string $column_name, string $post_type): void {
+ if ($post_type !== 'aksrt_forum_topic' || $column_name !== 'aksrt_sticky') {
+ return;
+ }
+ ?>
+
+ post_type !== 'aksrt_forum_topic') {
+ return;
+ }
+ ?>
+
+
Date: Wed, 15 Jul 2026 02:24:00 +0800
Subject: [PATCH 2/2] feat(admin): topic governance meta box and product
category term fields
Add native side meta box for forum topics (plate/sticky/lock/review/pay
visibility) and taxonomy form fields for aksrt_product_cat inheritance
settings. Source-only changes; no SPA build artifacts.
---
functions.php | 5 +
inc/bootstrap.php | 1 +
inc/classes/class-aksrt-shop-term-meta.php | 112 ++++++++++
.../forum/class-aksrt-topic-meta-box.php | 191 ++++++++++++++++++
4 files changed, 309 insertions(+)
create mode 100644 inc/classes/forum/class-aksrt-topic-meta-box.php
diff --git a/functions.php b/functions.php
index 36ac10c3..e5e06080 100644
--- a/functions.php
+++ b/functions.php
@@ -311,6 +311,11 @@ if (is_admin() && class_exists('AKSRT_Plate_Meta_Box')) {
if (is_admin() && class_exists('AKSRT_Topic_Admin_List')) {
AKSRT_Topic_Admin_List::get_instance()->init();
}
+// 论坛帖子治理 meta box
+if (is_admin() && class_exists('AKSRT_Topic_Meta_Box')) {
+ AKSRT_Topic_Meta_Box::get_instance()->init();
+}
+
diff --git a/inc/bootstrap.php b/inc/bootstrap.php
index 6f09a3ec..21fcc75a 100644
--- a/inc/bootstrap.php
+++ b/inc/bootstrap.php
@@ -324,6 +324,7 @@ require_once AKSRT_DIR . '/inc/classes/shop/class-aksrt-product-meta-box.php';
require_once AKSRT_DIR . '/inc/classes/shop/class-aksrt-product-variants-meta-box.php';
require_once AKSRT_DIR . '/inc/classes/forum/class-aksrt-plate-meta-box.php';
require_once AKSRT_DIR . '/inc/classes/forum/class-aksrt-topic-admin-list.php';
+require_once AKSRT_DIR . '/inc/classes/forum/class-aksrt-topic-meta-box.php';
require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-1.php';
require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-2.php';
require_once AKSRT_DIR . '/inc/classes/shop/shop-traits/trait-aksrt-shop-part-3.php';
diff --git a/inc/classes/class-aksrt-shop-term-meta.php b/inc/classes/class-aksrt-shop-term-meta.php
index 3f1a7568..b6873863 100644
--- a/inc/classes/class-aksrt-shop-term-meta.php
+++ b/inc/classes/class-aksrt-shop-term-meta.php
@@ -39,6 +39,12 @@ class AKSRT_Shop_Term_Meta {
add_action('shop_discount_edit_form_fields', [$this, 'render_discount_edit_fields'], 10, 1);
add_action('created_shop_discount', [$this, 'save_discount_term_fields']);
add_action('edited_shop_discount', [$this, 'save_discount_term_fields']);
+
+ // Product category inheritance fields.
+ add_action('aksrt_product_cat_add_form_fields', [$this, 'render_cat_add_fields']);
+ add_action('aksrt_product_cat_edit_form_fields', [$this, 'render_cat_edit_fields'], 10, 1);
+ add_action('created_aksrt_product_cat', [$this, 'save_cat_term_fields']);
+ add_action('edited_aksrt_product_cat', [$this, 'save_cat_term_fields']);
}
// ─── Taxonomy Registration ───────────────────────────────────
@@ -565,4 +571,110 @@ class AKSRT_Shop_Term_Meta {
update_term_meta($term_id, $key, $value);
}
}
+
+ public function render_cat_add_fields(): void {
+ foreach ($this->get_cat_field_definitions() as $key => $def) {
+ echo '';
+ echo '';
+ $this->render_cat_field_control($key, $def['default'] ?? '', false);
+ echo '
';
+ }
+ }
+
+ public function render_cat_edit_fields($term): void {
+ if (!($term instanceof WP_Term)) {
+ return;
+ }
+ foreach ($this->get_cat_field_definitions() as $key => $def) {
+ $value = get_term_meta($term->term_id, $key, true);
+ if ($value === '' || $value === false) {
+ $value = $def['default'] ?? '';
+ }
+ echo ' | ';
+ $this->render_cat_field_control($key, $value, true);
+ echo ' |
';
+ }
+ }
+
+ /**
+ * @param mixed $value
+ */
+ private function render_cat_field_control(string $key, $value, bool $edit): void {
+ $val = (string) $value;
+ if (in_array($key, ['shop_cat_guest_buy', 'shop_cat_email_fill', 'shop_cat_content_show_bg'], true)) {
+ echo '';
+ return;
+ }
+ if (in_array($key, ['shop_cat_service', 'shop_cat_single_tab', 'shop_cat_content_after'], true)) {
+ echo '';
+ return;
+ }
+ if ($key === 'shop_cat_shipping_fee') {
+ $opts = ['' => __('继承', 'aksrt'), 'free' => __('包邮', 'aksrt'), 'fixed' => __('固定运费', 'aksrt'), 'amount' => __('满额包邮', 'aksrt')];
+ echo '';
+ return;
+ }
+ if ($key === 'shop_cat_after_sale') {
+ $opts = ['' => __('继承', 'aksrt'), 'refund' => __('仅退款', 'aksrt'), 'refund_return' => __('退货退款', 'aksrt'), 'none' => __('不支持', 'aksrt')];
+ echo '';
+ return;
+ }
+ if ($key === 'shop_cat_content_layout') {
+ $opts = ['' => __('继承', 'aksrt'), 'adapt' => __('自适应', 'aksrt'), 'full' => __('通栏', 'aksrt'), 'sidebar' => __('侧栏', 'aksrt')];
+ echo '';
+ return;
+ }
+ if ($key === 'shop_cat_list_style') {
+ $opts = ['' => __('继承', 'aksrt'), 'default' => __('默认', 'aksrt'), 'card-lg' => __('大卡片', 'aksrt'), 'card-sm' => __('小卡片', 'aksrt')];
+ echo '';
+ return;
+ }
+ $type = $key === 'shop_cat_limit_buy' ? 'number' : 'text';
+ printf(
+ '',
+ esc_attr($type),
+ $edit ? 'regular-text' : '',
+ esc_attr($key),
+ esc_attr($key),
+ esc_attr($val)
+ );
+ }
+
+ public function save_cat_term_fields(int $term_id): void {
+ if (!current_user_can('manage_categories')) {
+ return;
+ }
+ foreach ($this->get_cat_field_definitions() as $key => $def) {
+ if (in_array($key, ['shop_cat_guest_buy', 'shop_cat_email_fill', 'shop_cat_content_show_bg'], true)) {
+ $raw = isset($_POST[$key]) ? '1' : '';
+ } else {
+ if (!isset($_POST[$key])) {
+ continue;
+ }
+ $raw = wp_unslash($_POST[$key]);
+ }
+ if (isset($def['sanitize']) && is_callable($def['sanitize'])) {
+ $value = call_user_func($def['sanitize'], $raw);
+ } else {
+ $value = sanitize_text_field((string) $raw);
+ }
+ update_term_meta($term_id, $key, $value);
+ }
+ }
}
diff --git a/inc/classes/forum/class-aksrt-topic-meta-box.php b/inc/classes/forum/class-aksrt-topic-meta-box.php
new file mode 100644
index 00000000..800088bc
--- /dev/null
+++ b/inc/classes/forum/class-aksrt-topic-meta-box.php
@@ -0,0 +1,191 @@
+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 = (string) (get_post_meta($post->ID, '_aksrt_visibility', true) ?: 'public');
+ $allow_view = (string) (get_post_meta($post->ID, '_aksrt_allow_view', true) ?: 'public');
+ $pay_price = (float) get_post_meta($post->ID, '_aksrt_pay_price', true);
+ $pay_credits= (int) get_post_meta($post->ID, '_aksrt_pay_credits', true);
+
+ $plates = get_posts([
+ 'post_type' => 'aksrt_forum_plate',
+ 'post_status' => 'publish',
+ 'posts_per_page' => 200,
+ 'orderby' => 'title',
+ 'order' => 'ASC',
+ ]);
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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);
+
+ $visibility = isset($_POST['aksrt_visibility']) ? sanitize_key((string) wp_unslash($_POST['aksrt_visibility'])) : 'public';
+ update_post_meta($post_id, '_aksrt_visibility', $visibility);
+
+ $allow_view = isset($_POST['aksrt_allow_view']) ? sanitize_key((string) wp_unslash($_POST['aksrt_allow_view'])) : 'public';
+ update_post_meta($post_id, '_aksrt_allow_view', $allow_view);
+
+ update_post_meta($post_id, '_aksrt_pay_price', isset($_POST['aksrt_pay_price']) ? max(0, (float) wp_unslash($_POST['aksrt_pay_price'])) : 0);
+ update_post_meta($post_id, '_aksrt_pay_credits', isset($_POST['aksrt_pay_credits']) ? max(0, (int) wp_unslash($_POST['aksrt_pay_credits'])) : 0);
+
+ // 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);
+ }
+ }
+ }
+}