PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / trunk
Forumax – AI Powered Advanced Community Forum Plugin vtrunk
2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 trunk 1.0.8 1.1.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 2.0.0 2.1.0 All 29 releases
bbp-core / includes / template-functions.php

template-functions.php in Forumax – AI Powered Advanced Community Forum Plugin trunk, at includes/template-functions.php

399 lines 11.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Template Functions for Forumax
4 *
5 * @package Forumax
6 */
7
8 defined( 'ABSPATH' ) || exit;
9
10 /**
11 * Register external template stack locations
12 * @return void
13 */
14 add_action( 'after_setup_theme', 'forumax_register_external_templates', 5 );
15 function forumax_register_external_templates() {
16
17 /**
18 * Forumax plugin templates - HIGH PRIORITY
19 * These are the main Forumax styled templates
20 */
21 bbp_register_template_stack( fn() => trailingslashit( FORUMAX_PATH . 'templates' ), 1 );
22
23 /**
24 * Theme override templates (only /forumax/ folder) - HIGHEST PRIORITY
25 * Allows themes to customize Forumax templates if needed
26 */
27 foreach ( forumax_get_theme_override_dirs() as $dir ) {
28 bbp_register_template_stack( fn() => trailingslashit( $dir ), 0 );
29 }
30 }
31
32 /**
33 * Get theme template directories that can override Forumax templates.
34 * Only checks for /forumax/ folder - theme's /bbpress/ folder is NOT used
35 * because Forumax provides its own styled templates.
36 *
37 * @return array
38 */
39 function forumax_get_theme_override_dirs() {
40 $dirs = [];
41 $themes = [ get_template_directory(), get_stylesheet_directory() ];
42
43 foreach ( array_unique( $themes ) as $theme ) {
44 $path = trailingslashit( $theme ) . 'forumax/';
45 if ( is_dir( $path ) ) {
46 $dirs[] = $path;
47 }
48 }
49
50 return $dirs;
51 }
52
53 /**
54 * Extend bbPress template locations
55 */
56 add_filter( 'bbp_get_template_locations', 'forumax_extend_template_locations', 10, 2 );
57 function forumax_extend_template_locations( $locations ) {
58
59 foreach ( [ 'forumax', 'bbpress' ] as $slug ) {
60 if ( ! in_array( $slug, $locations, true ) ) {
61 array_unshift( $locations, $slug );
62 }
63 }
64
65 return $locations;
66 }
67
68 /**
69 * Detect Hello theme family (Hello Elementor, Hello Biz, and child themes).
70 *
71 * @return bool
72 */
73 function forumax_is_hello_theme() {
74 $theme = wp_get_theme();
75 $stylesheet = $theme->get_stylesheet();
76 $template = $theme->get_template();
77
78 $hello_slugs = array( 'hello-elementor', 'hello-biz' );
79
80 foreach ( $hello_slugs as $slug ) {
81 if ( $slug === $template || 0 === strpos( $template, $slug ) ) {
82 return true;
83 }
84
85 if ( $slug === $stylesheet || 0 === strpos( $stylesheet, $slug ) ) {
86 return true;
87 }
88 }
89
90 return false;
91 }
92
93 /**
94 * Ensure Forumax templates are preferred on Hello theme.
95 *
96 * @param array $stack Template stack locations.
97 * @return array
98 */
99 add_filter( 'bbp_get_template_stack', 'forumax_force_templates_on_hello', 1 );
100 function forumax_force_templates_on_hello( $stack ) {
101 if ( ! forumax_is_hello_theme() || ! function_exists( 'bbp_add_template_stack_locations' ) ) {
102 return $stack;
103 }
104
105 $paths = bbp_add_template_stack_locations( array( trailingslashit( FORUMAX_PATH . 'templates' ) ) );
106 foreach ( array_reverse( (array) $paths ) as $path ) {
107 array_unshift( $stack, $path );
108 }
109
110 return array_values( array_unique( $stack ) );
111 }
112
113 /**
114 * Force Forumax forum archive template on Hello theme.
115 *
116 * Uses template_include filter (which runs after all template hierarchy filters)
117 * because Hello Elementor doesn't have archive.php, so archive_template filter
118 * never fires - WordPress falls back to index.php directly.
119 *
120 * @param string $template Current template path.
121 * @return string
122 */
123 add_filter( 'template_include', 'forumax_force_forum_archive_template_on_hello', 99 );
124 function forumax_force_forum_archive_template_on_hello( $template ) {
125 if ( ! forumax_is_hello_theme() || ! function_exists( 'bbp_is_forum_archive' ) ) {
126 return $template;
127 }
128
129 // Only override on bbPress forum archive pages.
130 if ( bbp_is_forum_archive() ) {
131 $hello_template = FORUMAX_PATH . 'templates/hello-archive-forum.php';
132 if ( file_exists( $hello_template ) ) {
133 return $hello_template;
134 }
135 }
136
137 return $template;
138 }
139
140 /**
141 * Force Forumax bbPress user profile template on Hello themes.
142 *
143 * Hello Elementor/Hello Biz can fall back to their 404 template when bbPress
144 * user rewrite rules are missing/out-of-date. This guarantees rendering of
145 * the user profile screen for URLs like `/forums/users/<nicename>/`.
146 *
147 * @param string $template Current template path.
148 * @return string
149 */
150 add_filter( 'template_include', 'forumax_force_user_profile_template_on_hello', 98 );
151 function forumax_force_user_profile_template_on_hello( $template ) {
152 if ( ! forumax_is_hello_theme() || ! function_exists( 'bbp_get_root_slug' ) ) {
153 return $template;
154 }
155
156 if ( ! isset( $_SERVER['REQUEST_URI'] ) ) {
157 return $template;
158 }
159
160 $path = (string) wp_parse_url( (string) $_SERVER['REQUEST_URI'], PHP_URL_PATH );
161 $path = trim( $path, '/' );
162 if ( '' === $path ) {
163 return $template;
164 }
165
166 $root_slug = trim( (string) bbp_get_root_slug(), '/' );
167 if ( '' === $root_slug ) {
168 return $template;
169 }
170
171 // Require /{root}/ prefix.
172 $root_prefix = $root_slug . '/';
173 if ( 0 !== strpos( $path, $root_prefix ) ) {
174 return $template;
175 }
176
177 $after_root = substr( $path, strlen( $root_prefix ) );
178 $parts = array_values( array_filter( explode( '/', (string) $after_root ) ) );
179 if ( count( $parts ) < 2 ) {
180 return $template;
181 }
182
183 $user_base = trim( (string) get_option( '_bbp_user_slug', 'users' ), '/' );
184 if ( '' === $user_base ) {
185 $user_base = 'users';
186 }
187
188 $alt_base = ( 'users' === $user_base ) ? 'user' : 'users';
189 if ( $parts[0] !== $user_base && $parts[0] !== $alt_base ) {
190 return $template;
191 }
192
193 $user_nicename = sanitize_title( (string) $parts[1] );
194 if ( '' === $user_nicename ) {
195 return $template;
196 }
197
198 $the_user = get_user_by( 'slug', $user_nicename );
199 if ( empty( $the_user ) || empty( $the_user->ID ) || ( function_exists( 'bbp_user_has_profile' ) && ! bbp_user_has_profile( $the_user->ID ) ) ) {
200 return $template;
201 }
202
203 // Pass data to the template.
204 set_query_var( 'forumax_hello_user_id', (int) $the_user->ID );
205 set_query_var( 'forumax_hello_user_section', isset( $parts[2] ) ? sanitize_title( (string) $parts[2] ) : '' );
206
207 $hello_template = FORUMAX_PATH . 'templates/hello-single-user.php';
208 if ( file_exists( $hello_template ) ) {
209 return $hello_template;
210 }
211
212 return $template;
213 }
214
215 /**
216 * Add rewrite aliases for bbPress user profiles.
217 *
218 * Some setups (or migrations) end up with links like `/forums/users/admin/`
219 * while the active bbPress "User base" might be `user` (or vice versa).
220 * Injecting aliases at runtime avoids 404s without requiring a rewrite flush.
221 *
222 * @param array $rules
223 * @return array
224 */
225 add_filter( 'rewrite_rules_array', 'forumax_add_bbpress_user_rewrite_aliases', 20 );
226 function forumax_add_bbpress_user_rewrite_aliases( $rules ) {
227 if ( ! function_exists( 'bbp_get_root_slug' ) || ! function_exists( 'bbp_get_user_rewrite_id' ) ) {
228 return $rules;
229 }
230
231 $root_slug = trim( (string) bbp_get_root_slug(), '/' );
232 if ( '' === $root_slug ) {
233 return $rules;
234 }
235
236 $user_base = trim( (string) get_option( '_bbp_user_slug', 'users' ), '/' );
237 if ( '' === $user_base ) {
238 $user_base = 'users';
239 }
240
241 $alt_base = ( 'users' === $user_base ) ? 'user' : 'users';
242
243 $root_regex = preg_quote( $root_slug, '!' );
244 $bases = array_values( array_unique( array( $user_base, $alt_base ) ) );
245 $add = array();
246
247 foreach ( $bases as $base ) {
248 $base_regex = preg_quote( $base, '!' );
249
250 // User profile root: /{root}/{users|user}/{nicename}/
251 $profile_rule = '^' . $root_regex . '/' . $base_regex . '/([^/]+)/?$';
252 if ( ! isset( $rules[ $profile_rule ] ) ) {
253 $add[ $profile_rule ] = 'index.php?' . bbp_get_user_rewrite_id() . '=$matches[1]';
254 }
255 }
256
257 return $add + $rules;
258 }
259
260 /**
261 * Map bbPress user profile URLs at runtime (no rewrite flush).
262 *
263 * When rewrite rules are missing/out-of-date, Hello themes often fall through
264 * to their 404 template for URLs like `/forums/users/<nicename>/`. Other themes
265 * may mask the issue by having alternate templates/routes.
266 *
267 * This ensures Hello themes always populate bbPress query vars early enough
268 * for bbPress's `bbp_parse_query()` to flag the request as a user profile.
269 *
270 * @param WP $wp
271 * @return void
272 */
273 add_action( 'parse_request', 'forumax_map_bbpress_user_request_on_hello', 1 );
274 function forumax_map_bbpress_user_request_on_hello( $wp ) {
275 if ( ! forumax_is_hello_theme() || is_admin() ) {
276 return;
277 }
278
279 if ( ! ( $wp instanceof WP ) ) {
280 return;
281 }
282
283 if ( ! function_exists( 'bbp_get_root_slug' ) || ! function_exists( 'bbp_get_user_rewrite_id' ) ) {
284 return;
285 }
286
287 $user_rewrite_id = bbp_get_user_rewrite_id();
288 if ( empty( $user_rewrite_id ) ) {
289 return;
290 }
291
292 // If bbPress already matched, don't interfere.
293 if ( ! empty( $wp->query_vars[ $user_rewrite_id ] ) ) {
294 return;
295 }
296
297 $request = isset( $wp->request ) ? trim( (string) $wp->request, '/' ) : '';
298 if ( '' === $request ) {
299 return;
300 }
301
302 $root_slug = trim( (string) bbp_get_root_slug(), '/' );
303 if ( '' === $root_slug ) {
304 return;
305 }
306
307 $root_prefix = $root_slug . '/';
308 if ( 0 !== strpos( $request, $root_prefix ) ) {
309 return;
310 }
311
312 $after_root = substr( $request, strlen( $root_prefix ) );
313 if ( '' === $after_root ) {
314 return;
315 }
316
317 $user_base = trim( (string) get_option( '_bbp_user_slug', 'users' ), '/' );
318 if ( '' === $user_base ) {
319 $user_base = 'users';
320 }
321
322 $alt_base = ( 'users' === $user_base ) ? 'user' : 'users';
323
324 // Match: (users|user)/{nicename}/(optional section)
325 $base_regex = '(?:' . preg_quote( $user_base, '!' ) . '|' . preg_quote( $alt_base, '!' ) . ')';
326 if ( ! preg_match( '!' . '^' . $base_regex . '/([^/]+)(?:/(.*))?$' . '!' , $after_root, $m ) ) {
327 return;
328 }
329
330 $user_nicename = sanitize_title( $m[1] );
331 $section = isset( $m[2] ) ? trim( (string) $m[2], '/' ) : '';
332
333 if ( '' === $user_nicename ) {
334 return;
335 }
336
337 // Set the primary bbPress user query var.
338 $wp->query_vars[ $user_rewrite_id ] = $user_nicename;
339
340 // Also set the bbPress query name for consistency.
341 $wp->query_vars['_bbp_query_name'] = 'bbp_single_user';
342
343 // Map optional sections (favorites/subscriptions/topics/replies/engagements/edit).
344 if ( '' !== $section ) {
345 $section_first = explode( '/', $section )[0];
346
347 if ( function_exists( 'bbp_get_edit_slug' ) && ( bbp_get_edit_slug() === $section_first ) ) {
348 $wp->query_vars[ bbp_get_edit_rewrite_id() ] = '1';
349 } elseif ( function_exists( 'bbp_get_user_favorites_slug' ) && ( bbp_get_user_favorites_slug() === $section_first ) ) {
350 $wp->query_vars[ bbp_get_user_favorites_rewrite_id() ] = bbp_get_user_favorites_slug();
351 } elseif ( function_exists( 'bbp_get_user_subscriptions_slug' ) && ( bbp_get_user_subscriptions_slug() === $section_first ) ) {
352 $wp->query_vars[ bbp_get_user_subscriptions_rewrite_id() ] = bbp_get_user_subscriptions_slug();
353 } elseif ( function_exists( 'bbp_get_topic_archive_slug' ) && ( bbp_get_topic_archive_slug() === $section_first ) ) {
354 $wp->query_vars[ bbp_get_user_topics_rewrite_id() ] = '1';
355 } elseif ( function_exists( 'bbp_get_reply_archive_slug' ) && ( bbp_get_reply_archive_slug() === $section_first ) ) {
356 $wp->query_vars[ bbp_get_user_replies_rewrite_id() ] = '1';
357 } elseif ( function_exists( 'bbp_get_user_engagements_slug' ) && ( bbp_get_user_engagements_slug() === $section_first ) ) {
358 $wp->query_vars[ bbp_get_user_engagements_rewrite_id() ] = '1';
359 }
360 }
361 }
362
363 /**
364 * Banner preset background styles
365 *
366 * @return array[]|string[]
367 */
368 function forumax_banner_bg_style() {
369 return [
370 'color' => FORUMAX_IMG . '/options/color.png',
371 'faded-sun' => FORUMAX_IMG . '/options/faded-sun.jpg',
372 'happy-journey' => FORUMAX_IMG . '/options/happy-journey.jpg',
373 'apparent-circle' => FORUMAX_IMG . '/options/apparent-circle.jpg',
374 'soft-weather' => FORUMAX_IMG . '/options/soft-weather.jpg',
375 'romantic-sun' => FORUMAX_IMG . '/options/romantic-sun.jpg',
376 'teal-eclipse' => FORUMAX_IMG . '/options/teal-eclipse.jpg',
377 ];
378 }
379
380
381
382 /**
383 * Image from Settings
384 *
385 * @param string $option_id
386 * @param string $class
387 * @param string $alt
388 */
389 function get_image_from_settings( string $option_id = '', string $class = '', string $alt = '' ):void {
390 $image = forumax_get_opt($option_id) ?? '';
391
392 // Check if the image has an 'id' or a 'url' and display accordingly
393 if ( ! empty($image['id']) ) {
394 echo wp_get_attachment_image($image['id'], 'full', '' );
395 } elseif ( !empty($image['url']) ) {
396 echo "<img src='{$image['url']}'>";
397 }
398 }
399