array( 'name' => __('Banners', 'aksrt'), 'singular_name' => __('Banner', 'aksrt'), ), 'public' => false, 'show_ui' => false, 'show_in_rest' => true, 'supports' => array('title'), 'menu_icon' => 'dashicons-images-alt2', 'capability_type' => 'post', 'capabilities' => array('create_posts' => 'manage_options'), 'map_meta_cap' => true, )); } add_action('init', 'aksrt_register_banner_cpt'); // ============================================================ // §3.7 Register Topics taxonomy for posts (专题分类) // ============================================================ function aksrt_register_topics_taxonomy() { register_taxonomy('topics', 'post', [ 'labels' => [ 'name' => __('专题', 'aksrt'), 'singular_name' => __('专题', 'aksrt'), 'search_items' => __('搜索专题', 'aksrt'), 'all_items' => __('所有专题', 'aksrt'), 'edit_item' => __('编辑专题', 'aksrt'), 'add_new_item' => __('添加专题', 'aksrt'), 'menu_name' => __('专题', 'aksrt'), ], 'hierarchical' => true, 'public' => true, 'show_in_rest' => true, 'show_admin_column' => true, 'rewrite' => ['slug' => 'topics'], ]); } add_action('init', 'aksrt_register_topics_taxonomy'); // ============================================================ // 注册自定义文章类型 - Forum Topic & 分类法 - Forum Board // ============================================================ function aksrt_register_forum_cpt() { // Respect bbs_s switch — skip CPT registration when forum is disabled. // Admin context always registers so the backend settings page works. if (!is_admin() && class_exists('AKSRT_Settings')) { $forum = AKSRT_Settings::get_forum_settings(); if (empty($forum['enabled'])) { return; } } // Read custom slugs from settings when available $plate_slug = 'board'; $topic_slug = 'topic'; if (class_exists('AKSRT_Settings')) { $forum = AKSRT_Settings::get_forum_settings(); $plate_slug = !empty($forum['other']['plate_slug']) ? $forum['other']['plate_slug'] : 'board'; $topic_slug = !empty($forum['other']['posts_slug']) ? $forum['other']['posts_slug'] : 'topic'; } // Forum Board taxonomy register_taxonomy('aksrt_forum_board', 'aksrt_forum_topic', [ 'labels' => [ 'name' => __('论坛版块', 'aksrt'), 'singular_name' => __('版块', 'aksrt'), 'search_items' => __('搜索版块', 'aksrt'), 'all_items' => __('所有版块', 'aksrt'), 'edit_item' => __('编辑版块', 'aksrt'), 'add_new_item' => __('添加版块', 'aksrt'), ], 'hierarchical' => true, 'public' => true, 'show_in_rest' => true, 'show_admin_column' => true, 'rewrite' => ['slug' => $plate_slug], ]); // Forum Tag taxonomy register_taxonomy('aksrt_forum_tag', 'aksrt_forum_topic', [ 'labels' => [ 'name' => __('论坛标签', 'aksrt'), 'singular_name' => __('标签', 'aksrt'), 'search_items' => __('搜索标签', 'aksrt'), 'all_items' => __('所有标签', 'aksrt'), 'edit_item' => __('编辑标签', 'aksrt'), 'add_new_item' => __('添加标签', 'aksrt'), ], 'hierarchical' => false, 'public' => true, 'show_in_rest' => true, 'show_admin_column' => false, 'rewrite' => ['slug' => 'forum-tag'], ]); // Forum Topic taxonomy (话题,单选,区别于标签) register_taxonomy('aksrt_forum_topic_cat', 'aksrt_forum_topic', [ 'labels' => [ 'name' => __('论坛话题', 'aksrt'), 'singular_name' => __('话题', 'aksrt'), 'search_items' => __('搜索话题', 'aksrt'), 'all_items' => __('所有话题', 'aksrt'), 'edit_item' => __('编辑话题', 'aksrt'), 'add_new_item' => __('添加话题', 'aksrt'), ], 'hierarchical' => false, 'public' => true, 'show_in_rest' => true, 'show_admin_column' => true, 'rewrite' => ['slug' => 'forum-topic'], ]); // Forum Topic CPT register_post_type('aksrt_forum_topic', [ 'labels' => [ 'name' => __('论坛主题', 'aksrt'), 'singular_name' => __('主题', 'aksrt'), 'add_new_item' => __('发布新主题', 'aksrt'), 'edit_item' => __('编辑主题', 'aksrt'), 'view_item' => __('查看主题', 'aksrt'), ], 'public' => true, 'show_in_rest' => true, 'has_archive' => true, 'menu_icon' => 'dashicons-comments', 'supports' => ['title', 'editor', 'author', 'comments', 'thumbnail', 'excerpt'], 'capability_type' => 'post', 'rewrite' => ['slug' => $topic_slug], ]); } add_action('init', 'aksrt_register_forum_cpt'); // ============================================================ // 注册板块 CPT (aksrt_forum_plate) + 板块分区 taxonomy (aksrt_plate_cat) // §7.0 plate CPT 脚手架:板块从 taxonomy 迁移为独立 CPT, // 支持作者(超级版主)、正文/摘要/封面、层级父子、独立 meta 扩展位。 // ============================================================ function aksrt_register_forum_plate_cpt() { if (!is_admin() && class_exists('AKSRT_Settings')) { $forum = AKSRT_Settings::get_forum_settings(); if (empty($forum['enabled'])) { return; } } $plate_slug = 'board'; if (class_exists('AKSRT_Settings')) { $forum = AKSRT_Settings::get_forum_settings(); $plate_slug = !empty($forum['other']['plate_slug']) ? $forum['other']['plate_slug'] : 'board'; } // Plate category taxonomy (分区) register_taxonomy('aksrt_plate_cat', 'aksrt_forum_plate', [ 'labels' => [ 'name' => __('板块分区', 'aksrt'), 'singular_name' => __('分区', 'aksrt'), 'search_items' => __('搜索分区', 'aksrt'), 'all_items' => __('所有分区', 'aksrt'), 'edit_item' => __('编辑分区', 'aksrt'), 'add_new_item' => __('添加分区', 'aksrt'), ], 'hierarchical' => true, 'public' => true, 'show_in_rest' => true, 'show_admin_column' => true, 'rewrite' => ['slug' => 'plate-cat'], ]); // Plate CPT (板块) register_post_type('aksrt_forum_plate', [ 'labels' => [ 'name' => __('论坛版块', 'aksrt'), 'singular_name' => __('版块', 'aksrt'), 'add_new_item' => __('创建版块', 'aksrt'), 'edit_item' => __('编辑版块', 'aksrt'), 'view_item' => __('查看版块', 'aksrt'), 'search_items' => __('搜索版块', 'aksrt'), 'not_found' => __('未找到版块', 'aksrt'), 'not_found_in_trash' => __('回收站中未找到版块', 'aksrt'), ], 'public' => true, 'hierarchical' => true, 'show_in_rest' => true, 'has_archive' => false, 'menu_icon' => 'dashicons-grid-view', 'supports' => ['title', 'editor', 'author', 'excerpt', 'thumbnail', 'page-attributes'], 'capability_type' => 'post', 'rewrite' => ['slug' => $plate_slug, 'with_front' => false], 'show_in_menu' => false, ]); // Keep aksrt_forum_topic assignable to plates via taxonomy bridge register_taxonomy_for_object_type('aksrt_forum_board', 'aksrt_forum_topic'); } add_action('init', 'aksrt_register_forum_plate_cpt'); // ============================================================ // §7.0 forum_post CPT 对齐:注册帖子 meta 扩展位地基 // 为 aksrt_forum_topic 注册全部 meta key,提供类型安全 + REST 暴露。 // ============================================================ function aksrt_register_forum_topic_meta() { $post_type = 'aksrt_forum_topic'; $meta_fields = [ // 基础治理 meta (已有,补注册) '_aksrt_visibility' => ['type' => 'string', 'default' => 'public'], '_aksrt_review_status' => ['type' => 'string', 'default' => ''], '_aksrt_sticky' => ['type' => 'integer', 'default' => 0], '_aksrt_featured' => ['type' => 'integer', 'default' => 0], '_aksrt_locked' => ['type' => 'integer', 'default' => 0], '_aksrt_highlight' => ['type' => 'string', 'default' => ''], '_aksrt_views' => ['type' => 'integer', 'default' => 0], '_aksrt_moderation_note' => ['type' => 'string', 'default' => ''], '_aksrt_moderated_by' => ['type' => 'integer', 'default' => 0], '_aksrt_moderated_at' => ['type' => 'string', 'default' => ''], // 帖子类型 + 问答状态 (Wave3) '_aksrt_bbs_type' => ['type' => 'string', 'default' => 'standard'], '_aksrt_question_status' => ['type' => 'integer', 'default' => 0], '_aksrt_adopted_comment' => ['type' => 'integer', 'default' => 0], // 投票 (已有,补注册) '_aksrt_vote_enabled' => ['type' => 'integer', 'default' => 0], '_aksrt_vote_title' => ['type' => 'string', 'default' => ''], '_aksrt_vote_multiple' => ['type' => 'integer', 'default' => 0], '_aksrt_vote_type' => ['type' => 'string', 'default' => 'standard'], '_aksrt_vote_expiry_days' => ['type' => 'integer', 'default' => 0], // 评分 (Wave3) '_aksrt_score' => ['type' => 'integer', 'default' => 0], '_aksrt_recommend_score' => ['type' => 'number', 'default' => 0], '_aksrt_hot_rewarded' => ['type' => 'integer', 'default' => 0], // 收藏 (Wave3) '_aksrt_favorite_count' => ['type' => 'integer', 'default' => 0], // 封面扩展位 (§7.3 待实现) '_aksrt_cover_type' => ['type' => 'string', 'default' => ''], '_aksrt_cover_image' => ['type' => 'string', 'default' => ''], '_aksrt_featured_slide' => ['type' => 'array', 'default' => []], '_aksrt_featured_video' => ['type' => 'string', 'default' => ''], '_aksrt_cover_ratio' => ['type' => 'string', 'default' => '16:9'], // 付费内容扩展位 (§7.3 待实现) '_aksrt_allow_view' => ['type' => 'string', 'default' => 'public'], '_aksrt_pay_price' => ['type' => 'number', 'default' => 0], '_aksrt_pay_vip_price' => ['type' => 'number', 'default' => 0], '_aksrt_pay_credits' => ['type' => 'integer', 'default' => 0], '_aksrt_pay_hide_part' => ['type' => 'integer', 'default' => 0], // 状态工作流扩展位 (Wave4) '_aksrt_closed' => ['type' => 'integer', 'default' => 0], '_aksrt_hidden' => ['type' => 'integer', 'default' => 0], // 板块 CPT 关联 (§7.0 新增) '_aksrt_plate_id' => ['type' => 'integer', 'default' => 0], ]; foreach ($meta_fields as $key => $args) { $schema = [ 'type' => $args['type'], 'description' => $key, 'single' => true, 'default' => $args['default'], 'show_in_rest' => false, ]; if ($args['type'] === 'array') { $schema['show_in_rest'] = false; $schema['type'] = 'array'; } register_post_meta($post_type, $key, $schema); } // Plate CPT meta registration $plate_meta = [ '_aksrt_sort_order' => ['type' => 'integer', 'default' => 0], '_aksrt_icon' => ['type' => 'string', 'default' => ''], '_aksrt_moderators' => ['type' => 'array', 'default' => []], '_aksrt_moderator_roles' => ['type' => 'array', 'default' => []], '_aksrt_posts_count' => ['type' => 'integer', 'default' => 0], '_aksrt_reply_count' => ['type' => 'integer', 'default' => 0], '_aksrt_today_reply_count' => ['type' => 'integer', 'default' => 0], '_aksrt_plate_views' => ['type' => 'integer', 'default' => 0], '_aksrt_follow_count' => ['type' => 'integer', 'default' => 0], '_aksrt_last_reply' => ['type' => 'string', 'default' => ''], '_aksrt_last_post' => ['type' => 'string', 'default' => ''], '_aksrt_allow_view' => ['type' => 'string', 'default' => 'public'], '_aksrt_add_limit' => ['type' => 'integer', 'default' => 0], ]; foreach ($plate_meta as $key => $args) { register_post_meta('aksrt_forum_plate', $key, [ 'type' => $args['type'] === 'array' ? 'array' : $args['type'], 'description' => $key, 'single' => true, 'default' => $args['default'], 'show_in_rest' => false, ]); } } add_action('init', 'aksrt_register_forum_topic_meta'); // Include forum topics in frontend search results (§7.10). add_action('pre_get_posts', function ($query) { if (!is_admin() && $query->is_main_query() && $query->is_search()) { $post_types = $query->get('post_type'); if (empty($post_types) || $post_types === 'post') { $query->set('post_type', ['post', 'page', 'aksrt_forum_topic']); } elseif (is_array($post_types) && !in_array('aksrt_forum_topic', $post_types, true)) { $post_types[] = 'aksrt_forum_topic'; $query->set('post_type', $post_types); } } }); // ============================================================