| 1 |
<?php |
| 2 |
namespace features; |
| 3 |
|
| 4 |
/** |
| 5 |
* Forumax Auto Close Topics |
| 6 |
* Automatically close topics with no new replies after a configurable number of days. |
| 7 |
*/ |
| 8 |
class forumax_auto_close_topics { |
| 9 |
|
| 10 |
/** |
| 11 |
* Constructor |
| 12 |
*/ |
| 13 |
public function __construct() { |
| 14 |
add_action( 'init', [ $this, 'schedule_events' ] ); |
| 15 |
add_action( 'frmx_auto_close_stale_topics', [ $this, 'close_stale_topics' ] ); |
| 16 |
} |
| 17 |
|
| 18 |
/** |
| 19 |
* Schedule or unschedule the cron event based on settings. |
| 20 |
*/ |
| 21 |
public function schedule_events() { |
| 22 |
if ( forumax_get_opt( 'auto_close_stale_topics' ) ) { |
| 23 |
if ( ! wp_next_scheduled( 'frmx_auto_close_stale_topics' ) ) { |
| 24 |
wp_schedule_event( time(), 'daily', 'frmx_auto_close_stale_topics' ); |
| 25 |
} |
| 26 |
} else { |
| 27 |
$timestamp = wp_next_scheduled( 'frmx_auto_close_stale_topics' ); |
| 28 |
if ( $timestamp ) { |
| 29 |
wp_unschedule_event( $timestamp, 'frmx_auto_close_stale_topics' ); |
| 30 |
} |
| 31 |
} |
| 32 |
} |
| 33 |
|
| 34 |
/** |
| 35 |
* Close stale topics. |
| 36 |
*/ |
| 37 |
public function close_stale_topics() { |
| 38 |
if ( ! forumax_get_opt( 'auto_close_stale_topics' ) ) { |
| 39 |
return; |
| 40 |
} |
| 41 |
|
| 42 |
$days = absint( forumax_get_opt( 'auto_close_days', 90 ) ); |
| 43 |
if ( $days < 1 ) { |
| 44 |
return; |
| 45 |
} |
| 46 |
|
| 47 |
$cutoff = date( 'Y-m-d H:i:s', strtotime( "-{$days} days" ) ); |
| 48 |
|
| 49 |
// Get open topics with no recent replies |
| 50 |
$args = [ |
| 51 |
'post_type' => 'topic', |
| 52 |
'post_status' => 'publish', |
| 53 |
'posts_per_page' => 50, // Batch to avoid timeouts |
| 54 |
'meta_query' => [ |
| 55 |
[ |
| 56 |
'key' => '_bbp_last_active_time', |
| 57 |
'value' => $cutoff, |
| 58 |
'compare' => '<', |
| 59 |
'type' => 'DATETIME', |
| 60 |
], |
| 61 |
], |
| 62 |
'fields' => 'ids', |
| 63 |
]; |
| 64 |
|
| 65 |
$stale_topics = get_posts( $args ); |
| 66 |
|
| 67 |
if ( ! empty( $stale_topics ) ) { |
| 68 |
foreach ( $stale_topics as $topic_id ) { |
| 69 |
// Skip already closed topics (though query checks post_status=publish, bbp_is_topic_closed checks meta) |
| 70 |
if ( bbp_is_topic_closed( $topic_id ) ) { |
| 71 |
continue; |
| 72 |
} |
| 73 |
// Skip sticky topics (they're intentionally persistent) |
| 74 |
if ( bbp_is_topic_sticky( $topic_id ) || bbp_is_topic_super_sticky( $topic_id ) ) { |
| 75 |
continue; |
| 76 |
} |
| 77 |
|
| 78 |
bbp_close_topic( $topic_id ); |
| 79 |
|
| 80 |
// Add a meta flag so admins know it was auto-closed |
| 81 |
update_post_meta( $topic_id, '_frmx_auto_closed', current_time( 'mysql' ) ); |
| 82 |
} |
| 83 |
} |
| 84 |
} |
| 85 |
} |
| 86 |
|
| 87 |
// Instantiate the class. |
| 88 |
new forumax_auto_close_topics(); |
| 89 |
|