trailingslashit( FORUMAX_PATH . 'templates' ), 1 ); /** * Theme override templates (only /forumax/ folder) - HIGHEST PRIORITY * Allows themes to customize Forumax templates if needed */ foreach ( forumax_get_theme_override_dirs() as $dir ) { bbp_register_template_stack( fn() => trailingslashit( $dir ), 0 ); } } /** * Get theme template directories that can override Forumax templates. * Only checks for /forumax/ folder - theme's /bbpress/ folder is NOT used * because Forumax provides its own styled templates. * * @return array */ function forumax_get_theme_override_dirs() { $dirs = []; $themes = [ get_template_directory(), get_stylesheet_directory() ]; foreach ( array_unique( $themes ) as $theme ) { $path = trailingslashit( $theme ) . 'forumax/'; if ( is_dir( $path ) ) { $dirs[] = $path; } } return $dirs; } /** * Extend bbPress template locations */ add_filter( 'bbp_get_template_locations', 'forumax_extend_template_locations', 10, 2 ); function forumax_extend_template_locations( $locations ) { foreach ( [ 'forumax', 'bbpress' ] as $slug ) { if ( ! in_array( $slug, $locations, true ) ) { array_unshift( $locations, $slug ); } } return $locations; } /** * Detect Hello theme family (Hello Elementor, Hello Biz, and child themes). * * @return bool */ function forumax_is_hello_theme() { $theme = wp_get_theme(); $stylesheet = $theme->get_stylesheet(); $template = $theme->get_template(); $hello_slugs = array( 'hello-elementor', 'hello-biz' ); foreach ( $hello_slugs as $slug ) { if ( $slug === $template || 0 === strpos( $template, $slug ) ) { return true; } if ( $slug === $stylesheet || 0 === strpos( $stylesheet, $slug ) ) { return true; } } return false; } /** * Ensure Forumax templates are preferred on Hello theme. * * @param array $stack Template stack locations. * @return array */ add_filter( 'bbp_get_template_stack', 'forumax_force_templates_on_hello', 1 ); function forumax_force_templates_on_hello( $stack ) { if ( ! forumax_is_hello_theme() || ! function_exists( 'bbp_add_template_stack_locations' ) ) { return $stack; } $paths = bbp_add_template_stack_locations( array( trailingslashit( FORUMAX_PATH . 'templates' ) ) ); foreach ( array_reverse( (array) $paths ) as $path ) { array_unshift( $stack, $path ); } return array_values( array_unique( $stack ) ); } /** * Force Forumax forum archive template on Hello theme. * * Uses template_include filter (which runs after all template hierarchy filters) * because Hello Elementor doesn't have archive.php, so archive_template filter * never fires - WordPress falls back to index.php directly. * * @param string $template Current template path. * @return string */ add_filter( 'template_include', 'forumax_force_forum_archive_template_on_hello', 99 ); function forumax_force_forum_archive_template_on_hello( $template ) { if ( ! forumax_is_hello_theme() || ! function_exists( 'bbp_is_forum_archive' ) ) { return $template; } // Only override on bbPress forum archive pages. if ( bbp_is_forum_archive() ) { $hello_template = FORUMAX_PATH . 'templates/hello-archive-forum.php'; if ( file_exists( $hello_template ) ) { return $hello_template; } } return $template; } /** * Force Forumax bbPress user profile template on Hello themes. * * Hello Elementor/Hello Biz can fall back to their 404 template when bbPress * user rewrite rules are missing/out-of-date. This guarantees rendering of * the user profile screen for URLs like `/forums/users//`. * * @param string $template Current template path. * @return string */ add_filter( 'template_include', 'forumax_force_user_profile_template_on_hello', 98 ); function forumax_force_user_profile_template_on_hello( $template ) { if ( ! forumax_is_hello_theme() || ! function_exists( 'bbp_get_root_slug' ) ) { return $template; } if ( ! isset( $_SERVER['REQUEST_URI'] ) ) { return $template; } $path = (string) wp_parse_url( (string) $_SERVER['REQUEST_URI'], PHP_URL_PATH ); $path = trim( $path, '/' ); if ( '' === $path ) { return $template; } $root_slug = trim( (string) bbp_get_root_slug(), '/' ); if ( '' === $root_slug ) { return $template; } // Require /{root}/ prefix. $root_prefix = $root_slug . '/'; if ( 0 !== strpos( $path, $root_prefix ) ) { return $template; } $after_root = substr( $path, strlen( $root_prefix ) ); $parts = array_values( array_filter( explode( '/', (string) $after_root ) ) ); if ( count( $parts ) < 2 ) { return $template; } $user_base = trim( (string) get_option( '_bbp_user_slug', 'users' ), '/' ); if ( '' === $user_base ) { $user_base = 'users'; } $alt_base = ( 'users' === $user_base ) ? 'user' : 'users'; if ( $parts[0] !== $user_base && $parts[0] !== $alt_base ) { return $template; } $user_nicename = sanitize_title( (string) $parts[1] ); if ( '' === $user_nicename ) { return $template; } $the_user = get_user_by( 'slug', $user_nicename ); if ( empty( $the_user ) || empty( $the_user->ID ) || ( function_exists( 'bbp_user_has_profile' ) && ! bbp_user_has_profile( $the_user->ID ) ) ) { return $template; } // Pass data to the template. set_query_var( 'forumax_hello_user_id', (int) $the_user->ID ); set_query_var( 'forumax_hello_user_section', isset( $parts[2] ) ? sanitize_title( (string) $parts[2] ) : '' ); $hello_template = FORUMAX_PATH . 'templates/hello-single-user.php'; if ( file_exists( $hello_template ) ) { return $hello_template; } return $template; } /** * Add rewrite aliases for bbPress user profiles. * * Some setups (or migrations) end up with links like `/forums/users/admin/` * while the active bbPress "User base" might be `user` (or vice versa). * Injecting aliases at runtime avoids 404s without requiring a rewrite flush. * * @param array $rules * @return array */ add_filter( 'rewrite_rules_array', 'forumax_add_bbpress_user_rewrite_aliases', 20 ); function forumax_add_bbpress_user_rewrite_aliases( $rules ) { if ( ! function_exists( 'bbp_get_root_slug' ) || ! function_exists( 'bbp_get_user_rewrite_id' ) ) { return $rules; } $root_slug = trim( (string) bbp_get_root_slug(), '/' ); if ( '' === $root_slug ) { return $rules; } $user_base = trim( (string) get_option( '_bbp_user_slug', 'users' ), '/' ); if ( '' === $user_base ) { $user_base = 'users'; } $alt_base = ( 'users' === $user_base ) ? 'user' : 'users'; $root_regex = preg_quote( $root_slug, '!' ); $bases = array_values( array_unique( array( $user_base, $alt_base ) ) ); $add = array(); foreach ( $bases as $base ) { $base_regex = preg_quote( $base, '!' ); // User profile root: /{root}/{users|user}/{nicename}/ $profile_rule = '^' . $root_regex . '/' . $base_regex . '/([^/]+)/?$'; if ( ! isset( $rules[ $profile_rule ] ) ) { $add[ $profile_rule ] = 'index.php?' . bbp_get_user_rewrite_id() . '=$matches[1]'; } } return $add + $rules; } /** * Map bbPress user profile URLs at runtime (no rewrite flush). * * When rewrite rules are missing/out-of-date, Hello themes often fall through * to their 404 template for URLs like `/forums/users//`. Other themes * may mask the issue by having alternate templates/routes. * * This ensures Hello themes always populate bbPress query vars early enough * for bbPress's `bbp_parse_query()` to flag the request as a user profile. * * @param WP $wp * @return void */ add_action( 'parse_request', 'forumax_map_bbpress_user_request_on_hello', 1 ); function forumax_map_bbpress_user_request_on_hello( $wp ) { if ( ! forumax_is_hello_theme() || is_admin() ) { return; } if ( ! ( $wp instanceof WP ) ) { return; } if ( ! function_exists( 'bbp_get_root_slug' ) || ! function_exists( 'bbp_get_user_rewrite_id' ) ) { return; } $user_rewrite_id = bbp_get_user_rewrite_id(); if ( empty( $user_rewrite_id ) ) { return; } // If bbPress already matched, don't interfere. if ( ! empty( $wp->query_vars[ $user_rewrite_id ] ) ) { return; } $request = isset( $wp->request ) ? trim( (string) $wp->request, '/' ) : ''; if ( '' === $request ) { return; } $root_slug = trim( (string) bbp_get_root_slug(), '/' ); if ( '' === $root_slug ) { return; } $root_prefix = $root_slug . '/'; if ( 0 !== strpos( $request, $root_prefix ) ) { return; } $after_root = substr( $request, strlen( $root_prefix ) ); if ( '' === $after_root ) { return; } $user_base = trim( (string) get_option( '_bbp_user_slug', 'users' ), '/' ); if ( '' === $user_base ) { $user_base = 'users'; } $alt_base = ( 'users' === $user_base ) ? 'user' : 'users'; // Match: (users|user)/{nicename}/(optional section) $base_regex = '(?:' . preg_quote( $user_base, '!' ) . '|' . preg_quote( $alt_base, '!' ) . ')'; if ( ! preg_match( '!' . '^' . $base_regex . '/([^/]+)(?:/(.*))?$' . '!' , $after_root, $m ) ) { return; } $user_nicename = sanitize_title( $m[1] ); $section = isset( $m[2] ) ? trim( (string) $m[2], '/' ) : ''; if ( '' === $user_nicename ) { return; } // Set the primary bbPress user query var. $wp->query_vars[ $user_rewrite_id ] = $user_nicename; // Also set the bbPress query name for consistency. $wp->query_vars['_bbp_query_name'] = 'bbp_single_user'; // Map optional sections (favorites/subscriptions/topics/replies/engagements/edit). if ( '' !== $section ) { $section_first = explode( '/', $section )[0]; if ( function_exists( 'bbp_get_edit_slug' ) && ( bbp_get_edit_slug() === $section_first ) ) { $wp->query_vars[ bbp_get_edit_rewrite_id() ] = '1'; } elseif ( function_exists( 'bbp_get_user_favorites_slug' ) && ( bbp_get_user_favorites_slug() === $section_first ) ) { $wp->query_vars[ bbp_get_user_favorites_rewrite_id() ] = bbp_get_user_favorites_slug(); } elseif ( function_exists( 'bbp_get_user_subscriptions_slug' ) && ( bbp_get_user_subscriptions_slug() === $section_first ) ) { $wp->query_vars[ bbp_get_user_subscriptions_rewrite_id() ] = bbp_get_user_subscriptions_slug(); } elseif ( function_exists( 'bbp_get_topic_archive_slug' ) && ( bbp_get_topic_archive_slug() === $section_first ) ) { $wp->query_vars[ bbp_get_user_topics_rewrite_id() ] = '1'; } elseif ( function_exists( 'bbp_get_reply_archive_slug' ) && ( bbp_get_reply_archive_slug() === $section_first ) ) { $wp->query_vars[ bbp_get_user_replies_rewrite_id() ] = '1'; } elseif ( function_exists( 'bbp_get_user_engagements_slug' ) && ( bbp_get_user_engagements_slug() === $section_first ) ) { $wp->query_vars[ bbp_get_user_engagements_rewrite_id() ] = '1'; } } } /** * Banner preset background styles * * @return array[]|string[] */ function forumax_banner_bg_style() { return [ 'color' => FORUMAX_IMG . '/options/color.png', 'faded-sun' => FORUMAX_IMG . '/options/faded-sun.jpg', 'happy-journey' => FORUMAX_IMG . '/options/happy-journey.jpg', 'apparent-circle' => FORUMAX_IMG . '/options/apparent-circle.jpg', 'soft-weather' => FORUMAX_IMG . '/options/soft-weather.jpg', 'romantic-sun' => FORUMAX_IMG . '/options/romantic-sun.jpg', 'teal-eclipse' => FORUMAX_IMG . '/options/teal-eclipse.jpg', ]; } /** * Image from Settings * * @param string $option_id * @param string $class * @param string $alt */ function get_image_from_settings( string $option_id = '', string $class = '', string $alt = '' ):void { $image = forumax_get_opt($option_id) ?? ''; // Check if the image has an 'id' or a 'url' and display accordingly if ( ! empty($image['id']) ) { echo wp_get_attachment_image($image['id'], 'full', '' ); } elseif ( !empty($image['url']) ) { echo ""; } }