通过把下面的代码复制粘贴到您的 WordPress 主题下 functions.php 里面就可以了,然后在设置选项会出现在主题的 自定义器设置页面上。
内容目录 / TOC
代码一:
/**
* 高级版 - 带管理界面的自动关闭功能
*/
// 添加设置选项到 WordPress 自定义器
add_action('customize_register', 'bbp_auto_close_customize_register');
function bbp_auto_close_customize_register($wp_customize) {
$wp_customize->add_section('bbp_auto_close_section', array(
'title' => __('bbPress 自动关闭设置', 'bbpress'),
'priority' => 160,
));
$wp_customize->add_setting('bbp_auto_close_days', array(
'default' => 30,
'sanitize_callback' => 'absint',
));
$wp_customize->add_control('bbp_auto_close_days', array(
'label' => __('自动关闭天数', 'bbpress'),
'section' => 'bbp_auto_close_section',
'type' => 'number',
'description' => __('主题在最后活动后多少天自动关闭', 'bbpress'),
));
$wp_customize->add_setting('bbp_auto_close_enabled', array(
'default' => true,
'sanitize_callback' => 'wp_validate_boolean',
));
$wp_customize->add_control('bbp_auto_close_enabled', array(
'label' => __('启用自动关闭', 'bbpress'),
'section' => 'bbp_auto_close_section',
'type' => 'checkbox',
));
}
// 核心自动关闭功能
add_action('init', 'bbp_advanced_auto_close_init');
function bbp_advanced_auto_close_init() {
if (!get_theme_mod('bbp_auto_close_enabled', true)) {
return;
}
$close_days = get_theme_mod('bbp_auto_close_days', 30);
// 使用 WordPress Cron 定时执行
if (!wp_next_scheduled('bbp_daily_auto_close_check')) {
wp_schedule_event(time(), 'daily', 'bbp_daily_auto_close_check');
}
add_action('bbp_daily_auto_close_check', 'bbp_execute_auto_close');
}
// 执行自动关闭
function bbp_execute_auto_close() {
$close_days = get_theme_mod('bbp_auto_close_days', 30);
$cutoff_time = strtotime('-' . $close_days . ' days');
$args = array(
'post_type' => bbp_get_topic_post_type(),
'post_status' => 'publish',
'posts_per_page' => -1,
'date_query' => array(
array(
'before' => date('Y-m-d', $cutoff_time),
'inclusive' => true,
),
),
'meta_query' => array(
array(
'key' => '_bbp_auto_closed',
'compare' => 'NOT EXISTS',
)
)
);
$old_topics = get_posts($args);
foreach ($old_topics as $topic) {
// 检查是否有新回复
$last_reply = bbp_get_topic_last_reply_id($topic->ID);
if ($last_reply) {
$reply_time = get_post_time('U', true, $last_reply);
if ($reply_time > $cutoff_time) {
continue; // 有新的回复,不关闭
}
}
// 关闭主题
wp_update_post(array(
'ID' => $topic->ID,
'post_status' => 'closed'
));
update_post_meta($topic->ID, '_bbp_auto_closed', current_time('mysql'));
// 可选:发送通知给主题作者
bbp_send_auto_close_notification($topic->ID, $close_days);
}
}
// 发送关闭通知
function bbp_send_auto_close_notification($topic_id, $days) {
$topic_author = get_post_field('post_author', $topic_id);
$user = get_userdata($topic_author);
$topic_title = get_the_title($topic_id);
$topic_link = get_permalink($topic_id);
$subject = sprintf(__('您的主题 "%s" 已自动关闭', 'bbpress'), $topic_title);
$message = sprintf(__(
'您好 %s,
您的主题 "%s" 由于在 %d 天内没有新活动,已被自动关闭。
您可以在此查看主题: %s
此操作是为了保持论坛内容的新鲜度和相关性。
谢谢,
论坛管理团队
', 'bbpress'), $user->display_name, $topic_title, $days, $topic_link);
wp_mail($user->user_email, $subject, $message);
}
// 清理 Cron 任务
register_deactivation_hook(__FILE__, 'bbp_auto_close_deactivation');
function bbp_auto_close_deactivation() {
$timestamp = wp_next_scheduled('bbp_daily_auto_close_check');
wp_unschedule_event($timestamp, 'bbp_daily_auto_close_check');
}代码二:
增强方法的代码,包含立即检查功能
-
将上面的完整代码添加到您的
functions.php文件中 -
初始化现有主题:
-
进入 WordPress 后台
-
转到 设置 → bbPress 自动关闭
-
点击”初始化所有主题元数据”按钮
-
这会为所有现有主题添加最后活动时间元数据
-
-
立即检查并关闭:
-
在同一页面,点击”立即检查并关闭旧主题”按钮
-
系统会立即检查并关闭所有符合条件的旧主题
-
-
配置设置:
-
设置自动关闭天数
-
启用/禁用自动关闭功能
-
选择要排除的版块
-
-
查看统计:
-
页面底部会显示统计信息
-
包括符合关闭条件的主题数量
-
下次自动检查时间
-
/**
* 增强版 - 带管理界面和立即检查功能的自动关闭
*/
// 添加管理页面
add_action('admin_menu', 'bbp_auto_close_admin_menu');
function bbp_auto_close_admin_menu() {
add_submenu_page(
'options-general.php',
'bbPress 自动关闭设置',
'bbPress 自动关闭',
'manage_options',
'bbp-auto-close',
'bbp_auto_close_admin_page'
);
}
// 管理页面内容
function bbp_auto_close_admin_page() {
?>
<div class="wrap">
<h1>bbPress 主题自动关闭设置</h1>
<form method="post" action="options.php">
<?php
settings_fields('bbp_auto_close_settings');
do_settings_sections('bbp_auto_close_settings');
?>
<table class="form-table">
<tr>
<th scope="row">自动关闭天数</th>
<td>
<input type="number"
name="bbp_auto_close_days"
value="<?php echo get_option('bbp_auto_close_days', 30); ?>"
min="1" max="365">
<p class="description">主题在最后活动后多少天自动关闭</p>
</td>
</tr>
<tr>
<th scope="row">启用自动关闭</th>
<td>
<label>
<input type="checkbox"
name="bbp_auto_close_enabled"
value="1"
<?php checked(1, get_option('bbp_auto_close_enabled', 1)); ?>>
启用主题自动关闭功能
</label>
</td>
</tr>
<tr>
<th scope="row">排除版块</th>
<td>
<?php
$forums = get_posts(array(
'post_type' => 'forum',
'post_status' => 'publish',
'posts_per_page' => -1
));
$excluded_forums = get_option('bbp_auto_close_excluded_forums', array());
if (!is_array($excluded_forums)) {
$excluded_forums = array();
}
foreach ($forums as $forum) {
?>
<label style="display: block; margin-bottom: 5px;">
<input type="checkbox"
name="bbp_auto_close_excluded_forums[]"
value="<?php echo $forum->ID; ?>"
<?php checked(in_array($forum->ID, $excluded_forums)); ?>>
<?php echo esc_html($forum->post_title); ?>
</label>
<?php
}
?>
<p class="description">选择的版块将不会自动关闭主题</p>
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>
<hr>
<h2>立即检查并关闭旧主题</h2>
<p>点击下面的按钮立即检查所有现有主题,并关闭符合条件的旧主题。</p>
<form method="post" action="">
<?php wp_nonce_field('bbp_manual_auto_close', 'bbp_auto_close_nonce'); ?>
<input type="submit"
name="bbp_manual_close_old"
class="button button-primary"
value="立即检查并关闭旧主题">
<input type="submit"
name="bbp_init_metadata"
class="button button-secondary"
value="初始化所有主题元数据">
</form>
<?php
// 处理手动关闭请求
if (isset($_POST['bbp_manual_close_old']) &&
wp_verify_nonce($_POST['bbp_auto_close_nonce'], 'bbp_manual_auto_close')) {
$closed_count = bbp_manual_close_old_topics();
echo '<div class="notice notice-success"><p>已检查并关闭了 ' . $closed_count . ' 个旧主题。</p></div>';
}
// 处理初始化元数据请求
if (isset($_POST['bbp_init_metadata']) &&
wp_verify_nonce($_POST['bbp_auto_close_nonce'], 'bbp_manual_auto_close')) {
bbp_initialize_all_topics_metadata();
echo '<div class="notice notice-success"><p>已初始化所有主题的元数据。</p></div>';
}
// 显示统计信息
bbp_show_auto_close_stats();
?>
</div>
<?php
}
// 注册设置
add_action('admin_init', 'bbp_auto_close_register_settings');
function bbp_auto_close_register_settings() {
register_setting('bbp_auto_close_settings', 'bbp_auto_close_days', array(
'type' => 'integer',
'default' => 30
));
register_setting('bbp_auto_close_settings', 'bbp_auto_close_enabled', array(
'type' => 'boolean',
'default' => true
));
register_setting('bbp_auto_close_settings', 'bbp_auto_close_excluded_forums', array(
'type' => 'array',
'default' => array()
));
}
// 手动立即检查并关闭旧主题
function bbp_manual_close_old_topics() {
if (!current_user_can('manage_options')) {
return 0;
}
$close_days = get_option('bbp_auto_close_days', 30);
$excluded_forums = get_option('bbp_auto_close_excluded_forums', array());
$cutoff_time = strtotime('-' . $close_days . ' days');
$closed_count = 0;
$args = array(
'post_type' => bbp_get_topic_post_type(),
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => '_bbp_last_reply_time',
'value' => $cutoff_time,
'compare' => '<=',
'type' => 'NUMERIC'
),
array(
'key' => '_bbp_last_reply_time',
'compare' => 'NOT EXISTS'
)
)
);
$old_topics = get_posts($args);
foreach ($old_topics as $topic) {
// 检查是否在排除的版块中
$forum_id = bbp_get_topic_forum_id($topic->ID);
if (in_array($forum_id, (array)$excluded_forums)) {
continue;
}
// 获取主题的最后活动时间
$last_reply_time = get_post_meta($topic->ID, '_bbp_last_reply_time', true);
if (!$last_reply_time) {
// 如果没有最后活动时间,使用主题创建时间
$last_reply_time = get_post_time('U', true, $topic->ID);
update_post_meta($topic->ID, '_bbp_last_reply_time', $last_reply_time);
}
// 检查是否需要关闭
if ($last_reply_time <= $cutoff_time) {
wp_update_post(array(
'ID' => $topic->ID,
'post_status' => 'closed'
));
update_post_meta($topic->ID, '_bbp_auto_closed', current_time('mysql'));
$closed_count++;
}
}
return $closed_count;
}
// 初始化所有主题的元数据
function bbp_initialize_all_topics_metadata() {
$args = array(
'post_type' => bbp_get_topic_post_type(),
'post_status' => 'any',
'posts_per_page' => -1
);
$topics = get_posts($args);
$count = 0;
foreach ($topics as $topic) {
$last_reply_time = get_post_meta($topic->ID, '_bbp_last_reply_time', true);
if (!$last_reply_time) {
$last_reply_id = bbp_get_topic_last_reply_id($topic->ID);
if ($last_reply_id) {
$last_reply_time = get_post_time('U', true, $last_reply_id);
} else {
$last_reply_time = get_post_time('U', true, $topic->ID);
}
update_post_meta($topic->ID, '_bbp_last_reply_time', $last_reply_time);
$count++;
}
}
update_option('bbp_initialized_all_topics', current_time('mysql'));
return $count;
}
// 显示统计信息
function bbp_show_auto_close_stats() {
$total_topics = wp_count_posts(bbp_get_topic_post_type());
$published = $total_topics->publish;
$closed = $total_topics->closed;
$close_days = get_option('bbp_auto_close_days', 30);
$cutoff_time = strtotime('-' . $close_days . ' days');
$args = array(
'post_type' => bbp_get_topic_post_type(),
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => '_bbp_last_reply_time',
'value' => $cutoff_time,
'compare' => '<=',
'type' => 'NUMERIC'
)
)
);
$old_topics = get_posts($args);
$eligible_count = count($old_topics);
?>
<h2>统计信息</h2>
<table class="widefat">
<thead>
<tr>
<th>项目</th>
<th>数量</th>
</tr>
</thead>
<tbody>
<tr>
<td>已发布主题总数</td>
<td><?php echo $published; ?></td>
</tr>
<tr>
<td>已关闭主题总数</td>
<td><?php echo $closed; ?></td>
</tr>
<tr>
<td>符合关闭条件的旧主题(超过 <?php echo $close_days; ?> 天)</td>
<td><?php echo $eligible_count; ?></td>
</tr>
<tr>
<td>下次自动检查时间</td>
<td>
<?php
$next_check = wp_next_scheduled('bbp_daily_auto_close_check');
if ($next_check) {
echo date('Y-m-d H:i:s', $next_check);
} else {
echo '未安排';
}
?>
</td>
</tr>
</tbody>
</table>
<?php
}
// 修改原有的 bbp_execute_auto_close 函数,包含排除版块检查
function bbp_execute_auto_close() {
if (!get_option('bbp_auto_close_enabled', true)) {
return;
}
$close_days = get_option('bbp_auto_close_days', 30);
$excluded_forums = get_option('bbp_auto_close_excluded_forums', array());
$cutoff_time = strtotime('-' . $close_days . ' days');
$args = array(
'post_type' => bbp_get_topic_post_type(),
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => '_bbp_last_reply_time',
'value' => $cutoff_time,
'compare' => '<=',
'type' => 'NUMERIC'
),
array(
'key' => '_bbp_auto_closed',
'compare' => 'NOT EXISTS',
)
)
);
$old_topics = get_posts($args);
$closed_count = 0;
foreach ($old_topics as $topic) {
// 检查是否在排除的版块中
$forum_id = bbp_get_topic_forum_id($topic->ID);
if (in_array($forum_id, (array)$excluded_forums)) {
continue;
}
// 关闭主题
wp_update_post(array(
'ID' => $topic->ID,
'post_status' => 'closed'
));
update_post_meta($topic->ID, '_bbp_auto_closed', current_time('mysql'));
$closed_count++;
// 可选:发送通知
bbp_send_auto_close_notification($topic->ID, $close_days);
}
// 记录关闭日志
if ($closed_count > 0) {
update_option('bbp_auto_close_last_run', array(
'time' => current_time('mysql'),
'count' => $closed_count
));
}
}添加 WP-CLI 命令(可选,用于批量处理)
如果您有大量主题,可以通过 WP-CLI 批量处理:
安装并配置好后,系统会:
- 每天自动检查一次
- 关闭所有超过设定天数的主题
- 发送邮件通知(如果配置了邮件功能)
- 排除指定版块的主题
这样,您的现有主题就会自动被检测并关闭,无需人工干预。
/**
* WP-CLI 命令支持
*/
if (defined('WP_CLI') && WP_CLI) {
class BBP_Auto_Close_CLI extends WP_CLI_Command {
/**
* 初始化所有主题的元数据
*/
public function init_metadata() {
WP_CLI::line('开始初始化主题元数据...');
$count = bbp_initialize_all_topics_metadata();
WP_CLI::success("已初始化 {$count} 个主题的元数据");
}
/**
* 立即关闭旧主题
*/
public function close_old() {
WP_CLI::line('开始检查并关闭旧主题...');
$count = bbp_manual_close_old_topics();
WP_CLI::success("已关闭 {$count} 个旧主题");
}
/**
* 查看统计信息
*/
public function stats() {
$total_topics = wp_count_posts(bbp_get_topic_post_type());
$published = $total_topics->publish;
$closed = $total_topics->closed;
WP_CLI::line("已发布主题: {$published}");
WP_CLI::line("已关闭主题: {$closed}");
}
}
WP_CLI::add_command('bbp auto-close', 'BBP_Auto_Close_CLI');
}