Files
wordpress-theme-aksrt/inc/core-hooks/part-1.php
T
kate522 78d3189f8f feat(forum): P1 topic coupons, P2 plate follow gateway, cash creator revenue
- Topic_Pay: soft/hard coupon validate, payable amount, free-after-discount, paid burn
- Creator_Revenue: settle content/topic/plate_follow cash (type=order), keep shop path
- Plate VIP1/VIP2 meta + resolve_plate_follow_pay_price via aksrt_get_user_vip_level
- New AKSRT_Plate_Follow_Pay REST multi-gateway; remove Credits×100 money bypass
- Frontend: cms-download plate_follow apiKind + forum-governance money cashier bridge
2026-07-15 13:04:04 +08:00

415 lines
21 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* AKSRT Theme Core Hooks
*
* 从 functions.php 中抽离的核心功能钩子:
* - Gravatar 头像源替换(4层拦截)
* - SMTP 邮件配置注入
* - 评论开关控制
* - Banner CPT 注册
* - Admin Bar 隐藏
*
* @package AKSRT
* @version 3.2.0
*/
defined('ABSPATH') || exit;
// ============================================================
// 评论功能开关
// ============================================================
add_filter('comments_open', function ($open, $post_id) {
if (!get_option('aksrt_comment_enabled', true)) {
return false;
}
return $open;
}, 10, 2);
add_filter('comment_text', function ($comment_text, $comment = null, $args = []) {
if (function_exists('aksrt_render_comment_content')) {
return aksrt_render_comment_content((string) $comment_text);
}
return $comment_text;
}, 20, 3);
// ============================================================
// 注册自定义文章类型 - Banner (REST API for SPA)
// ============================================================
function aksrt_register_banner_cpt() {
register_post_type('aksrt_banner', array(
'labels' => 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 / names from settings when available
$plate_slug = 'board';
$topic_slug = 'topic';
$forum_enabled = true;
$forum_settings = [];
if (class_exists('AKSRT_Settings')) {
$forum_settings = AKSRT_Settings::get_forum_settings();
$plate_slug = !empty($forum_settings['other']['plate_slug']) ? $forum_settings['other']['plate_slug'] : 'board';
$topic_slug = !empty($forum_settings['other']['posts_slug']) ? $forum_settings['other']['posts_slug'] : 'topic';
$forum_enabled = !empty($forum_settings['enabled']);
}
// Admin always registers types; menu follows bbs_s (zibll: show when forum on).
$forum_show_menu = is_admin() ? $forum_enabled : false;
$names = !empty($forum_settings['names']) ? $forum_settings['names'] : [];
$forum_label = sanitize_text_field((string) ($names['forum'] ?? __('论坛', 'aksrt')));
$posts_label = sanitize_text_field((string) ($names['posts'] ?? __('帖子', 'aksrt')));
$topic_label = sanitize_text_field((string) ($names['topic'] ?? __('话题', 'aksrt')));
$tag_label = sanitize_text_field((string) ($names['tag'] ?? __('标签', 'aksrt')));
// Legacy board taxonomy: keep rewrite/bridge, hide from admin (plate CPT is canonical).
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_ui' => false,
'show_in_menu' => false,
'show_in_rest' => true,
'show_admin_column' => false,
'rewrite' => ['slug' => $plate_slug],
]);
// Forum Tag taxonomy
register_taxonomy('aksrt_forum_tag', 'aksrt_forum_topic', [
'labels' => [
'name' => sprintf(/* translators: %s: forum name */ __('%s标签', 'aksrt'), $forum_label),
'singular_name' => $tag_label,
'search_items' => sprintf(/* translators: %s: tag name */ __('搜索%s', 'aksrt'), $tag_label),
'all_items' => sprintf(/* translators: %s: tag name */ __('所有%s', 'aksrt'), $tag_label),
'edit_item' => sprintf(/* translators: %s: tag name */ __('编辑%s', 'aksrt'), $tag_label),
'add_new_item' => sprintf(/* translators: %s: tag name */ __('添加%s', 'aksrt'), $tag_label),
'menu_name' => $tag_label,
],
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => $forum_show_menu,
'show_in_rest' => true,
'show_admin_column' => true,
'rewrite' => ['slug' => 'forum-tag'],
]);
// Forum Topic taxonomy (话题,单选,区别于标签)
register_taxonomy('aksrt_forum_topic_cat', 'aksrt_forum_topic', [
'labels' => [
'name' => sprintf(/* translators: %s: forum name */ __('%s话题', 'aksrt'), $forum_label),
'singular_name' => $topic_label,
'search_items' => sprintf(/* translators: %s: topic name */ __('搜索%s', 'aksrt'), $topic_label),
'all_items' => sprintf(/* translators: %s: topic name */ __('所有%s', 'aksrt'), $topic_label),
'edit_item' => sprintf(/* translators: %s: topic name */ __('编辑%s', 'aksrt'), $topic_label),
'add_new_item' => sprintf(/* translators: %s: topic name */ __('添加%s', 'aksrt'), $topic_label),
'menu_name' => $topic_label,
],
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => $forum_show_menu,
'show_in_rest' => true,
'show_admin_column' => true,
'rewrite' => ['slug' => 'forum-topic'],
]);
// Forum Topic CPT — native sidebar (zibll: forum_post @ pos 40)
register_post_type('aksrt_forum_topic', [
'labels' => [
'name' => $forum_label . $posts_label,
'singular_name' => $posts_label,
'add_new' => sprintf(/* translators: %s: posts name */ __('添加%s', 'aksrt'), $posts_label),
'add_new_item' => sprintf(/* translators: %s: posts name */ __('发布新%s', 'aksrt'), $posts_label),
'edit_item' => sprintf(/* translators: %s: posts name */ __('编辑%s', 'aksrt'), $posts_label),
'view_item' => sprintf(/* translators: %s: posts name */ __('查看%s', 'aksrt'), $posts_label),
'all_items' => sprintf(/* translators: %s: posts name */ __('所有%s', 'aksrt'), $posts_label),
'menu_name' => $forum_label . $posts_label,
],
'public' => true,
'show_ui' => true,
'show_in_menu' => $forum_show_menu,
'show_in_rest' => true,
'has_archive' => true,
'menu_position' => 40,
'menu_icon' => 'dashicons-buddicons-topics',
'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';
$forum_enabled = true;
$forum = [];
if (class_exists('AKSRT_Settings')) {
$forum = AKSRT_Settings::get_forum_settings();
$plate_slug = !empty($forum['other']['plate_slug']) ? $forum['other']['plate_slug'] : 'board';
$forum_enabled = !empty($forum['enabled']);
}
$forum_show_menu = is_admin() ? $forum_enabled : false;
$names = !empty($forum['names']) ? $forum['names'] : [];
$forum_label = sanitize_text_field((string) ($names['forum'] ?? __('论坛', 'aksrt')));
$plate_label = sanitize_text_field((string) ($names['plate'] ?? __('版块', 'aksrt')));
// Plate category taxonomy (分区)
register_taxonomy('aksrt_plate_cat', 'aksrt_forum_plate', [
'labels' => [
'name' => sprintf(/* translators: %s: plate name */ __('%s分区', 'aksrt'), $plate_label),
'singular_name' => __('分区', 'aksrt'),
'search_items' => __('搜索分区', 'aksrt'),
'all_items' => __('所有分区', 'aksrt'),
'edit_item' => __('编辑分区', 'aksrt'),
'add_new_item' => __('添加分区', 'aksrt'),
'menu_name' => __('分区', 'aksrt'),
],
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_in_menu' => $forum_show_menu,
'show_in_rest' => true,
'show_admin_column' => true,
'rewrite' => ['slug' => 'plate-cat'],
]);
// Plate CPT (板块) — native sidebar (zibll: plate @ pos 40)
register_post_type('aksrt_forum_plate', [
'labels' => [
'name' => $forum_label . $plate_label,
'singular_name' => $plate_label,
'add_new' => sprintf(/* translators: %s: plate name */ __('添加%s', 'aksrt'), $plate_label),
'add_new_item' => sprintf(/* translators: %s: plate name */ __('创建%s', 'aksrt'), $plate_label),
'edit_item' => sprintf(/* translators: %s: plate name */ __('编辑%s', 'aksrt'), $plate_label),
'view_item' => sprintf(/* translators: %s: plate name */ __('查看%s', 'aksrt'), $plate_label),
'search_items' => sprintf(/* translators: %s: plate name */ __('搜索%s', 'aksrt'), $plate_label),
'not_found' => sprintf(/* translators: %s: plate name */ __('未找到%s', 'aksrt'), $plate_label),
'not_found_in_trash' => sprintf(/* translators: %s: plate name */ __('回收站中未找到%s', 'aksrt'), $plate_label),
'all_items' => sprintf(/* translators: %s: plate name */ __('所有%s', 'aksrt'), $plate_label),
'menu_name' => $forum_label . $plate_label,
],
'public' => true,
'hierarchical' => true,
'show_ui' => true,
'show_in_menu' => $forum_show_menu,
'show_in_rest' => true,
'has_archive' => false,
'menu_position' => 40,
'menu_icon' => 'dashicons-buddicons-forums',
'supports' => ['title', 'editor', 'author', 'excerpt', 'thumbnail', 'page-attributes'],
'capability_type' => 'post',
'rewrite' => ['slug' => $plate_slug, 'with_front' => 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],
// 封面扩展位(论坛帖子封面;前台 forum-topic 渲染)
'_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'],
// 付费内容扩展位(论坛帖子付费门槛;前台 forum-topic 渲染)
'_aksrt_allow_view' => ['type' => 'string', 'default' => 'public'],
'_aksrt_pay_price' => ['type' => 'number', 'default' => 0],
'_aksrt_pay_vip_price' => ['type' => 'number', 'default' => 0], // legacy single VIP
'_aksrt_pay_vip1_price' => ['type' => 'number', 'default' => 0],
'_aksrt_pay_vip2_price' => ['type' => 'number', 'default' => 0],
'_aksrt_pay_credits' => ['type' => 'integer', 'default' => 0], // legacy alias of credits_cost
'_aksrt_credits_cost' => ['type' => 'integer', 'default' => 0], // runtime unlock price
'_aksrt_credits_vip1' => ['type' => 'integer', 'default' => 0],
'_aksrt_credits_vip2' => ['type' => 'integer', 'default' => 0],
'_aksrt_pay_hide_part' => ['type' => 'integer', 'default' => 0],
'_aksrt_virtual_sales' => ['type' => 'integer', 'default' => 0],
'_aksrt_topic_coupon_s' => ['type' => 'integer', 'default' => 0],
'_aksrt_visibility_roles' => ['type' => 'array', 'default' => []],
// 状态工作流扩展位 (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],
'_aksrt_follow_pay' => ['type' => 'integer', 'default' => 0],
'_aksrt_follow_pay_modo' => ['type' => 'string', 'default' => 'money'],
'_aksrt_follow_pay_price' => ['type' => 'number', 'default' => 0],
'_aksrt_follow_pay_points' => ['type' => 'integer', 'default' => 0],
'_aksrt_follow_pay_vip_price' => ['type' => 'number', 'default' => 0], // legacy read fallback → vip1
'_aksrt_follow_pay_vip1_price' => ['type' => 'number', 'default' => 0],
'_aksrt_follow_pay_vip2_price' => ['type' => 'number', '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);
}
}
});
// ============================================================