ID, 'topic' );
$d_users[$forumuser->ID] = $post_count;
}
arsort( $d_users );
// Optimization: Fetch all counts for the current parent in one query
$author_counts = [];
if ( ! empty( $d_users ) ) {
$sql = $wpdb->prepare( "
SELECT post_author, COUNT(*) as count
FROM $wpdb->posts
WHERE post_type = 'topic'
AND post_status = 'publish'
AND post_parent = %d
GROUP BY post_author
", $forum_id );
$results = $wpdb->get_results( $sql );
if ( $results ) {
foreach ( $results as $row ) {
$author_counts[ $row->post_author ] = $row->count;
}
}
}
$display_authors = [];
foreach ( $d_users as $key => $value ) {
// Use pre-fetched count
$users_post_count = isset( $author_counts[ $key ] ) ? $author_counts[ $key ] : 0;
if ( $users_post_count > 0 ) {
$display_authors[] = [
'ID' => $key,
'count' => $users_post_count
];
}
}
set_transient( $cache_key, $display_authors, HOUR_IN_SECONDS );
}
}
if ( ! empty( $display_authors ) ) {
foreach ( $display_authors as $author_data ) {
$user_id = $author_data['ID'];
$user = get_userdata( $user_id );
if ( ! $user ) {
continue;
}
$post_count = $author_data['count'];
echo '
';
}
}
}
/**
* Tag Name
*
* @return string
*/
public static function forum_topics_tags() {
global $wpdb;
$forum_id = get_queried_object_id();
$cache_key = 'frmx_tags_data_' . $forum_id;
$tags = get_transient( $cache_key );
if ( false === $tags ) {
$tags = $wpdb->get_results( $wpdb->prepare(
"SELECT DISTINCT t.term_id, t.name, t.slug, tt.count
FROM {$wpdb->terms} AS t
INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
INNER JOIN {$wpdb->term_relationships} AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
INNER JOIN {$wpdb->posts} AS p ON tr.object_id = p.ID
WHERE tt.taxonomy = 'topic-tag'
AND p.post_type = 'topic'
AND p.post_parent = %d
AND p.post_status = 'publish'
ORDER BY t.name ASC",
$forum_id
) );
set_transient( $cache_key, $tags, HOUR_IN_SECONDS );
}
if ( $tags ) {
foreach ( $tags as $tag ) {
$post_count = $tag->count;
echo '';
}
}
}
/**
* Invalidate forum caches when a topic is updated.
*
* @param int $topic_id Topic ID.
* @param int $forum_id Optional. Forum ID.
*/
public function invalidate_forum_caches( $topic_id, $forum_id = 0 ) {
if ( ! $forum_id ) {
$forum_id = bbp_get_topic_forum_id( $topic_id );
}
if ( $forum_id ) {
delete_transient( 'frmx_authors_data_' . $forum_id );
delete_transient( 'frmx_tags_data_' . $forum_id );
delete_transient( 'frmx_topic_count_publish_' . $forum_id );
delete_transient( 'frmx_topic_count_closed_' . $forum_id );
// Also invalidate global topic counts (forum_id = 0) used on main archive
delete_transient( 'frmx_topic_count_publish_0' );
delete_transient( 'frmx_topic_count_closed_0' );
}
}
/**
* Maybe invalidate forum caches when a post is trashed/untrashed/deleted.
*
* @param int $post_id Post ID.
*/
public function maybe_invalidate_forum_caches( $post_id ) {
if ( 'topic' === get_post_type( $post_id ) ) {
$this->invalidate_forum_caches( $post_id );
}
}
/**
* Tag Name
*
* @return void
*/
public static function forum_topics_open_close(): void
{
$is_queried_obj = is_singular('forum') ? get_queried_object_id() : false;
$user_id = is_singular('forum') ? false : bbp_get_displayed_user_field('ID');
// Get the active tab from the URL or default to 'open'
$active_tab = isset($_GET['tab']) && in_array($_GET['tab'], ['open', 'closed'], true) ? sanitize_text_field($_GET['tab']) : 'open';
// Count open and closed topics efficiently
$open_count = forumax_get_topic_count_by_status('publish', $is_queried_obj);
$closed_count = forumax_get_topic_count_by_status('closed', $is_queried_obj);
if ( in_array('bbp-user-page', get_body_class(), true) ) :
?>
get( 'post_type' ) !== 'topic' || $query->get( 'orderby' ) !== 'ID' ) {
return $posts;
}
// Only on first page
if ( $query->get( 'paged' ) > 1 ) {
return $posts;
}
// Prevent recursion
remove_filter( 'the_posts', [$this, 'inject_sticky_topics'], 10 );
$sticky_ids = [];
// Get Super Stickies
$super_stickies = bbp_get_super_stickies();
// Get Forum Stickies
$forum_id = 0;
if ( is_singular( 'forum' ) ) {
$forum_id = get_queried_object_id();
} elseif ( $query->get( 'post_parent' ) ) {
$post_parent = $query->get( 'post_parent' );
if ( is_numeric( $post_parent ) && $post_parent > 0 ) {
$forum_id = $post_parent;
}
}
$stickies = bbp_get_stickies( $forum_id );
$sticky_ids = array_unique(array_merge( $super_stickies, $stickies ) );
if ( ! empty( $sticky_ids ) ) {
$sticky_args = [
'post_type' => 'topic',
'post_parent' => 'any',
'post__in' => $sticky_ids,
'posts_per_page' => -1,
'orderby' => 'post__in',
'ignore_sticky_posts' => 1,
'no_found_rows' => true,
];
$sticky_query = new WP_Query( $sticky_args );
if ( $sticky_query->have_posts() ) {
$sticky_posts = $sticky_query->posts;
// Filter out stickies from the main posts to avoid duplicates
$posts = array_filter( $posts, function ( $p ) use ( $sticky_ids ) {
return !in_array( $p->ID, $sticky_ids, true );
});
// Prepend stickies
$posts = array_merge( $sticky_posts, $posts );
}
}
add_filter( 'the_posts', [ $this, 'inject_sticky_topics'], 10, 2 );
return $posts;
}
}
}
/**
* Get Forumax Forum Class instance
* Works with or without Forumax theme active
*
* @return Forumax_Forum_Class|null
*/
if ( ! function_exists( 'Forumax_Forum' ) ) {
function Forumax_Forum() {
if ( class_exists( 'Forumax_Forum_Class' ) ) {
return Forumax_Forum_Class::instance();
}
return null;
}
}