PluginProbe
bbPress / 2.6.17
bbPress v2.6.17
2.6.17 trunk 2.0 2.0-beta-1 2.0-beta-2b 2.0-beta-3 2.0-beta-3b 2.0-rc-2 2.0-rc-3 2.0-rc-4 2.0-rc-5 2.0.1 2.0.2 2.0.3 2.1 2.1-beta-1 2.1-rc1 2.1-rc2 2.1-rc3 2.1-rc4 2.1.1 2.1.2 2.1.3 2.2 2.2.1 All 72 releases
bbpress / includes / core / theme-compat.php

theme-compat.php in bbPress 2.6.17, at includes/core/theme-compat.php

1,096 lines 30.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * bbPress Theme Compatibility
5 *
6 * @package bbPress
7 * @subpackage Core
8 */
9
10 // Exit if accessed directly
11 defined( 'ABSPATH' ) || exit;
12
13 /** Theme Compat **************************************************************/
14
15 /**
16 * What follows is an attempt at intercepting the natural page load process
17 * to replace the_content() with the appropriate bbPress content.
18 *
19 * To do this, bbPress does several direct manipulations of global variables
20 * and forces them to do what they are not supposed to be doing.
21 *
22 * Don't try anything you're about to witness here, at home. Ever.
23 */
24
25 /** Base Class ****************************************************************/
26
27 /**
28 * Theme Compatibility base class
29 *
30 * This is only intended to be extended, and is included here as a basic guide
31 * for future Template Packs to use. @link bbp_setup_theme_compat()
32 *
33 * @since 2.0.0 bbPress (r3506)
34 */
35 class BBP_Theme_Compat {
36
37 /**
38 * Should be like:
39 *
40 * array(
41 * 'id' => ID of the theme (should be unique)
42 * 'name' => Name of the theme (should match style.css)
43 * 'version' => Theme version for cache busting scripts and styling
44 * 'dir' => Path to theme
45 * 'url' => URL to theme
46 * );
47 * @var array
48 */
49 private $_data = array();
50
51 /**
52 * Pass the $properties to the object on creation.
53 *
54 * @since 2.1.0 bbPress (r3926)
55 *
56 * @param array $properties
57 */
58 public function __construct( array $properties = array() ) {
59 $this->_data = $properties;
60 }
61
62 /**
63 * Set a theme's property.
64 *
65 * @since 2.1.0 bbPress (r3926)
66 *
67 * @param string $property
68 * @param mixed $value
69 * @return mixed
70 */
71 public function __set( $property, $value ) {
72 return $this->_data[ $property ] = $value;
73 }
74
75 /**
76 * Get a theme's property.
77 *
78 * @since 2.1.0 bbPress (r3926)
79 *
80 * @param string $property
81 * @param mixed $value
82 * @return mixed
83 */
84 public function __get( $property ) {
85 return array_key_exists( $property, $this->_data )
86 ? $this->_data[ $property ]
87 : '';
88 }
89
90 /**
91 * Return the template directory.
92 *
93 * @since 2.6.0 bbPress (r6548)
94 *
95 * @return string
96 */
97 public function get_dir() {
98 return $this->dir;
99 }
100 }
101
102 /** Functions *****************************************************************/
103
104 /**
105 * Setup the active template pack and register it's directory in the stack.
106 *
107 * @since 2.0.0 bbPress (r3311)
108 *
109 * @param BBP_Theme_Compat $theme
110 */
111 function bbp_setup_theme_compat( $theme = 'default' ) {
112 $bbp = bbpress();
113
114 // Bail if something already has this under control
115 if ( ! empty( $bbp->theme_compat->theme ) ) {
116 return;
117 }
118
119 // Fallback for empty theme
120 if ( empty( $theme ) ) {
121 $theme = 'default';
122 }
123
124 // If the theme is registered, use it and add it to the stack
125 if ( isset( $bbp->theme_compat->packages[ $theme ] ) ) {
126 $bbp->theme_compat->theme = $bbp->theme_compat->packages[ $theme ];
127
128 // Setup the template stack for the active template pack
129 bbp_register_template_stack( array( $bbp->theme_compat->theme, 'get_dir' ) );
130 }
131 }
132
133 /**
134 * Get the current template pack package.
135 *
136 * @since 2.6.0 bbPress (r6548)
137 *
138 * @return BBP_Theme_Compat
139 */
140 function bbp_get_current_template_pack() {
141 $bbp = bbpress();
142
143 // Theme was not setup, so fallback to an empty object
144 if ( empty( $bbp->theme_compat->theme ) ) {
145 $bbp->theme_compat->theme = new BBP_Theme_Compat();
146 }
147
148 // Filter & return
149 return apply_filters( 'bbp_get_current_template_pack', $bbp->theme_compat->theme );
150 }
151
152 /**
153 * Gets the id of the bbPress compatible theme used, in the event the
154 * currently active WordPress theme does not explicitly support bbPress.
155 * This can be filtered or set manually. Tricky theme authors can override the
156 * default and include their own bbPress compatibility layers for their themes.
157 *
158 * @since 2.0.0 bbPress (r3506)
159 *
160 * @return string
161 */
162 function bbp_get_theme_compat_id() {
163
164 // Filter & return
165 return apply_filters( 'bbp_get_theme_compat_id', bbp_get_current_template_pack()->id );
166 }
167
168 /**
169 * Gets the name of the bbPress compatible theme used, in the event the
170 * currently active WordPress theme does not explicitly support bbPress.
171 * This can be filtered or set manually. Tricky theme authors can override the
172 * default and include their own bbPress compatibility layers for their themes.
173 *
174 * @since 2.0.0 bbPress (r3506)
175 *
176 * @return string
177 */
178 function bbp_get_theme_compat_name() {
179
180 // Filter & return
181 return apply_filters( 'bbp_get_theme_compat_name', bbp_get_current_template_pack()->name );
182 }
183
184 /**
185 * Gets the version of the bbPress compatible theme used, in the event the
186 * currently active WordPress theme does not explicitly support bbPress.
187 * This can be filtered or set manually. Tricky theme authors can override the
188 * default and include their own bbPress compatibility layers for their themes.
189 *
190 * @since 2.0.0 bbPress (r3506)
191 *
192 * @return string
193 */
194 function bbp_get_theme_compat_version() {
195
196 // Filter & return
197 return apply_filters( 'bbp_get_theme_compat_version', bbp_get_current_template_pack()->version );
198 }
199
200 /**
201 * Gets the bbPress compatible theme used in the event the currently active
202 * WordPress theme does not explicitly support bbPress. This can be filtered,
203 * or set manually. Tricky theme authors can override the default and include
204 * their own bbPress compatibility layers for their themes.
205 *
206 * @since 2.0.0 bbPress (r3032)
207 *
208 * @return string
209 */
210 function bbp_get_theme_compat_dir() {
211
212 // Filter & return
213 return apply_filters( 'bbp_get_theme_compat_dir', bbp_get_current_template_pack()->dir );
214 }
215
216 /**
217 * Gets the bbPress compatible theme used in the event the currently active
218 * WordPress theme does not explicitly support bbPress. This can be filtered,
219 * or set manually. Tricky theme authors can override the default and include
220 * their own bbPress compatibility layers for their themes.
221 *
222 * @since 2.0.0 bbPress (r3032)
223 *
224 * @return string
225 */
226 function bbp_get_theme_compat_url() {
227
228 // Filter & return
229 return apply_filters( 'bbp_get_theme_compat_url', bbp_get_current_template_pack()->url );
230 }
231
232 /**
233 * Gets true/false if page is currently inside theme compatibility
234 *
235 * @since 2.0.0 bbPress (r3265)
236 *
237 * @return bool
238 */
239 function bbp_is_theme_compat_active() {
240 $bbp = bbpress();
241
242 if ( empty( $bbp->theme_compat->active ) ) {
243 return false;
244 }
245
246 return $bbp->theme_compat->active;
247 }
248
249 /**
250 * Sets true/false if page is currently inside theme compatibility
251 *
252 * @since 2.0.0 bbPress (r3265)
253 *
254 * @param bool $set
255 * @return bool
256 */
257 function bbp_set_theme_compat_active( $set = true ) {
258 bbpress()->theme_compat->active = $set;
259
260 return (bool) bbpress()->theme_compat->active;
261 }
262
263 /**
264 * Set the theme compat templates global
265 *
266 * Stash possible template files for the current query. Useful if plugins want
267 * to override them, or see what files are being scanned for inclusion.
268 *
269 * @since 2.0.0 bbPress (r3311)
270 */
271 function bbp_set_theme_compat_templates( $templates = array() ) {
272 bbpress()->theme_compat->templates = $templates;
273
274 return bbpress()->theme_compat->templates;
275 }
276
277 /**
278 * Set the theme compat template global
279 *
280 * Stash the template file for the current query. Useful if plugins want
281 * to override it, or see what file is being included.
282 *
283 * @since 2.0.0 bbPress (r3311)
284 */
285 function bbp_set_theme_compat_template( $template = '' ) {
286 bbpress()->theme_compat->template = $template;
287
288 return bbpress()->theme_compat->template;
289 }
290
291 /**
292 * Set the theme compat original_template global
293 *
294 * Stash the original template file for the current query. Useful for checking
295 * if bbPress was able to find a more appropriate template.
296 *
297 * @since 2.1.0 bbPress (r3926)
298 */
299 function bbp_set_theme_compat_original_template( $template = '' ) {
300 bbpress()->theme_compat->original_template = $template;
301
302 return bbpress()->theme_compat->original_template;
303 }
304
305 /**
306 * Is a template the original_template global
307 *
308 * Stash the original template file for the current query. Useful for checking
309 * if bbPress was able to find a more appropriate template.
310 *
311 * @since 2.1.0 bbPress (r3926)
312 */
313 function bbp_is_theme_compat_original_template( $template = '' ) {
314 $bbp = bbpress();
315
316 // Bail if no original template
317 if ( empty( $bbp->theme_compat->original_template ) ) {
318 return false;
319 }
320
321 return (bool) ( $bbp->theme_compat->original_template === $template );
322 }
323
324 /**
325 * Register a new bbPress theme package to the active theme packages array
326 *
327 * @since 2.1.0 bbPress (r3829)
328 *
329 * @param array $theme
330 */
331 function bbp_register_theme_package( $theme = array(), $override = true ) {
332
333 // Create new BBP_Theme_Compat object from the $theme array
334 if ( is_array( $theme ) ) {
335 $theme = new BBP_Theme_Compat( $theme );
336 }
337
338 // Bail if $theme isn't a proper object
339 if ( ! is_a( $theme, 'BBP_Theme_Compat' ) ) {
340 return;
341 }
342
343 // Load up bbPress
344 $bbp = bbpress();
345
346 // Only override if the flag is set and not previously registered
347 if ( empty( $bbp->theme_compat->packages[ $theme->id ] ) || ( true === $override ) ) {
348 $bbp->theme_compat->packages[ $theme->id ] = $theme;
349 }
350 }
351
352 /**
353 * This fun little function fills up some WordPress globals with dummy data to
354 * stop your average page template from complaining about it missing.
355 *
356 * @since 2.0.0 bbPress (r3108)
357 *
358 * @global WP_Query $wp_query
359 * @global object $post
360 * @param array $args
361 */
362 function bbp_theme_compat_reset_post( $args = array() ) {
363 global $wp_query, $post;
364
365 // Switch defaults if post is set
366 if ( isset( $wp_query->post ) ) {
367
368 // Use primarily Post attributes
369 $defaults = array(
370 'ID' => $wp_query->post->ID,
371 'post_status' => $wp_query->post->post_status,
372 'post_author' => $wp_query->post->post_author,
373 'post_parent' => $wp_query->post->post_parent,
374 'post_type' => $wp_query->post->post_type,
375 'post_date' => $wp_query->post->post_date,
376 'post_date_gmt' => $wp_query->post->post_date_gmt,
377 'post_modified' => $wp_query->post->post_modified,
378 'post_modified_gmt' => $wp_query->post->post_modified_gmt,
379 'post_content' => $wp_query->post->post_content,
380 'post_title' => $wp_query->post->post_title,
381 'post_excerpt' => $wp_query->post->post_excerpt,
382 'post_content_filtered' => $wp_query->post->post_content_filtered,
383 'post_mime_type' => $wp_query->post->post_mime_type,
384 'post_password' => $wp_query->post->post_password,
385 'post_name' => $wp_query->post->post_name,
386 'guid' => $wp_query->post->guid,
387 'menu_order' => $wp_query->post->menu_order,
388 'pinged' => $wp_query->post->pinged,
389 'to_ping' => $wp_query->post->to_ping,
390 'ping_status' => $wp_query->post->ping_status,
391 'comment_status' => $wp_query->post->comment_status,
392 'comment_count' => $wp_query->post->comment_count,
393 'filter' => $wp_query->post->filter,
394
395 'is_404' => false,
396 'is_page' => false,
397 'is_single' => false,
398 'is_archive' => false,
399 'is_tax' => false
400 );
401 } else {
402
403 // Get the default zero date value a single time
404 $zero_date = bbp_get_empty_datetime();
405
406 // Use primarily empty attributes
407 $defaults = array(
408 'ID' => -9999,
409 'post_status' => bbp_get_public_status_id(),
410 'post_author' => 0,
411 'post_parent' => 0,
412 'post_type' => 'page',
413 'post_date' => $zero_date,
414 'post_date_gmt' => $zero_date,
415 'post_modified' => $zero_date,
416 'post_modified_gmt' => $zero_date,
417 'post_content' => '',
418 'post_title' => '',
419 'post_excerpt' => '',
420 'post_content_filtered' => '',
421 'post_mime_type' => '',
422 'post_password' => '',
423 'post_name' => '',
424 'guid' => '',
425 'menu_order' => 0,
426 'pinged' => '',
427 'to_ping' => '',
428 'ping_status' => '',
429 'comment_status' => 'closed',
430 'comment_count' => 0,
431 'filter' => 'raw',
432
433 'is_404' => false,
434 'is_page' => false,
435 'is_single' => false,
436 'is_archive' => false,
437 'is_tax' => false
438 );
439 }
440
441 // Parse & filter
442 $dummy = bbp_parse_args( $args, $defaults, 'theme_compat_reset_post' );
443
444 // Bail if dummy post is empty
445 if ( empty( $dummy ) ) {
446 return;
447 }
448
449 // phpcs:disable WordPress.WP.GlobalVariablesOverride.Prohibited
450
451 // Set the $post global
452 $post = new WP_Post( (object) $dummy );
453
454 // Copy the new post global into the main $wp_query
455 $wp_query->post = $post;
456 $wp_query->posts = array( $post );
457
458 // Prevent comments form from appearing
459 $wp_query->post_count = 1;
460 $wp_query->is_404 = $dummy['is_404'];
461 $wp_query->is_page = $dummy['is_page'];
462 $wp_query->is_single = $dummy['is_single'];
463 $wp_query->is_archive = $dummy['is_archive'];
464 $wp_query->is_tax = $dummy['is_tax'];
465
466 // Reset is_singular based on page/single args
467 // https://bbpress.trac.wordpress.org/ticket/2545
468 $wp_query->is_singular = $wp_query->is_single;
469
470 // Clean up the dummy post
471 unset( $dummy );
472
473 // If we are resetting a post, we are in theme compat
474 bbp_set_theme_compat_active( true );
475 }
476
477 /**
478 * Reset main query vars and filter 'the_content' to output a bbPress
479 * template part as needed.
480 *
481 * @since 2.0.0 bbPress (r3032)
482 * @since 2.6.17 bbPress Added support for Block Themes
483 *
484 * @param string $template
485 */
486 function bbp_template_include_theme_compat( $template = '' ) {
487
488 /**
489 * Bail if a root template was already found. This prevents unintended
490 * recursive filtering of 'the_content'.
491 *
492 * @link https://bbpress.trac.wordpress.org/ticket/2429
493 */
494 if ( bbp_is_template_included() ) {
495 return $template;
496 }
497
498 /**
499 * If BuddyPress is activated at a network level, the action order is
500 * reversed, which causes the template integration to fail. If we're looking
501 * at a BuddyPress page here, bail to prevent the extra processing.
502 *
503 * This is a bit more brute-force than is probably necessary, but gets the
504 * job done while we work towards something more elegant.
505 */
506 if ( function_exists( 'is_buddypress' ) && is_buddypress() ) {
507 return $template;
508 }
509
510 // Define local variable(s)
511 $bbp_shortcodes = bbpress()->shortcodes;
512
513 // Bail if shortcodes are unset somehow
514 if ( ! is_a( $bbp_shortcodes, 'BBP_Shortcodes' ) ) {
515 return $template;
516 }
517
518 /** Users *************************************************************/
519
520 if ( bbp_is_single_user_edit() || bbp_is_single_user() ) {
521
522 // Reset post
523 bbp_theme_compat_reset_post(
524 array(
525 'ID' => 0,
526 'post_author' => 0,
527 'post_date' => bbp_get_empty_datetime(),
528 'post_content' => bbp_buffer_template_part( 'content', 'single-user', false ),
529 'post_type' => '',
530 'post_title' => bbp_get_displayed_user_field( 'display_name' ),
531 'post_status' => bbp_get_public_status_id(),
532 'is_archive' => false,
533 'comment_status' => 'closed'
534 )
535 );
536
537 /** Forums ************************************************************/
538
539 // Forum archive
540 } elseif ( bbp_is_forum_archive() ) {
541
542 // Page exists where this archive should be
543 $page = bbp_get_page_by_path( bbp_get_root_slug() );
544
545 // Should we replace the content...
546 if ( empty( $page->post_content ) ) {
547
548 // Use the topics archive
549 if ( 'topics' === bbp_show_on_root() ) {
550 $new_content = $bbp_shortcodes->display_topic_index();
551
552 // No page so show the archive
553 } else {
554 $new_content = $bbp_shortcodes->display_forum_index();
555 }
556
557 // ...or use the existing page content?
558 } else {
559 $new_content = apply_filters( 'the_content', $page->post_content );
560 }
561
562 // Should we replace the title...
563 if ( empty( $page->post_title ) ) {
564
565 // Use the topics archive
566 if ( 'topics' === bbp_show_on_root() ) {
567 $new_title = bbp_get_topic_archive_title();
568
569 // No page so show the archive
570 } else {
571 $new_title = bbp_get_forum_archive_title();
572 }
573
574 // ...or use the existing page title?
575 } else {
576 $new_title = apply_filters( 'the_title', $page->post_title, $page->ID );
577 }
578
579 // Reset post
580 bbp_theme_compat_reset_post(
581 array(
582 'ID' => ! empty( $page->ID ) ? $page->ID : 0,
583 'post_title' => $new_title,
584 'post_author' => 0,
585 'post_date' => bbp_get_empty_datetime(),
586 'post_content' => $new_content,
587 'post_type' => bbp_get_forum_post_type(),
588 'post_status' => bbp_get_public_status_id(),
589 'is_archive' => true,
590 'comment_status' => 'closed'
591 )
592 );
593
594 // Single Forum
595 } elseif ( bbp_is_forum_edit() ) {
596
597 // Reset post
598 bbp_theme_compat_reset_post(
599 array(
600 'ID' => bbp_get_forum_id(),
601 'post_title' => bbp_get_forum_title(),
602 'post_author' => bbp_get_forum_author_id(),
603 'post_date' => bbp_get_empty_datetime(),
604 'post_content' => $bbp_shortcodes->display_forum_form(),
605 'post_type' => bbp_get_forum_post_type(),
606 'post_status' => bbp_get_forum_visibility(),
607 'is_single' => true,
608 'comment_status' => 'closed'
609 )
610 );
611
612 // Lock the forum from other edits
613 bbp_set_post_lock( bbp_get_forum_id() );
614
615 } elseif ( bbp_is_single_forum() ) {
616
617 // Reset post
618 bbp_theme_compat_reset_post(
619 array(
620 'ID' => bbp_get_forum_id(),
621 'post_title' => bbp_get_forum_title(),
622 'post_author' => bbp_get_forum_author_id(),
623 'post_date' => bbp_get_empty_datetime(),
624 'post_content' => $bbp_shortcodes->display_forum( array( 'id' => bbp_get_forum_id() ) ),
625 'post_type' => bbp_get_forum_post_type(),
626 'post_status' => bbp_get_forum_visibility(),
627 'is_single' => true,
628 'comment_status' => 'closed'
629 )
630 );
631
632 /** Topics ************************************************************/
633
634 // Topic archive
635 } elseif ( bbp_is_topic_archive() ) {
636
637 // Page exists where this archive should be
638 $page = bbp_get_page_by_path( bbp_get_topic_archive_slug() );
639
640 // Should we replace the content...
641 if ( empty( $page->post_content ) ) {
642 $new_content = $bbp_shortcodes->display_topic_index();
643
644 // ...or use the existing page content?
645 } else {
646 $new_content = apply_filters( 'the_content', $page->post_content );
647 }
648
649 // Should we replace the title...
650 if ( empty( $page->post_title ) ) {
651 $new_title = bbp_get_topic_archive_title();
652
653 // ...or use the existing page title?
654 } else {
655 $new_title = apply_filters( 'the_title', $page->post_title );
656 }
657
658 // Reset post
659 bbp_theme_compat_reset_post(
660 array(
661 'ID' => ! empty( $page->ID ) ? $page->ID : 0,
662 'post_title' => bbp_get_topic_archive_title(),
663 'post_author' => 0,
664 'post_date' => bbp_get_empty_datetime(),
665 'post_content' => $new_content,
666 'post_type' => bbp_get_topic_post_type(),
667 'post_status' => bbp_get_public_status_id(),
668 'is_archive' => true,
669 'comment_status' => 'closed'
670 )
671 );
672
673 // Single Topic
674 } elseif ( bbp_is_topic_edit() || bbp_is_single_topic() ) {
675
676 // Split
677 if ( bbp_is_topic_split() ) {
678 $new_content = bbp_buffer_template_part( 'form', 'topic-split', false );
679
680 // Merge
681 } elseif ( bbp_is_topic_merge() ) {
682 $new_content = bbp_buffer_template_part( 'form', 'topic-merge', false );
683
684 // Edit
685 } elseif ( bbp_is_topic_edit() ) {
686 $new_content = $bbp_shortcodes->display_topic_form();
687
688 // Lock the topic from other edits
689 bbp_set_post_lock( bbp_get_topic_id() );
690
691 // Single
692 } else {
693 $new_content = $bbp_shortcodes->display_topic( array( 'id' => bbp_get_topic_id() ) );
694 }
695
696 // Reset post
697 bbp_theme_compat_reset_post(
698 array(
699 'ID' => bbp_get_topic_id(),
700 'post_title' => bbp_get_topic_title(),
701 'post_author' => bbp_get_topic_author_id(),
702 'post_date' => bbp_get_empty_datetime(),
703 'post_content' => $new_content,
704 'post_type' => bbp_get_topic_post_type(),
705 'post_status' => bbp_get_topic_status(),
706 'is_single' => true,
707 'comment_status' => 'closed'
708 )
709 );
710
711 /** Replies ***********************************************************/
712
713 // Reply archive
714 } elseif ( is_post_type_archive( bbp_get_reply_post_type() ) ) {
715
716 // Reset post
717 bbp_theme_compat_reset_post(
718 array(
719 'ID' => 0,
720 'post_title' => esc_html__( 'Replies', 'bbpress' ),
721 'post_author' => 0,
722 'post_date' => bbp_get_empty_datetime(),
723 'post_content' => '',
724 'post_type' => bbp_get_reply_post_type(),
725 'post_status' => bbp_get_public_status_id(),
726 'is_archive' => true,
727 'comment_status' => 'closed'
728 )
729 );
730
731 // Single Reply
732 } elseif ( bbp_is_reply_edit() || bbp_is_single_reply() ) {
733
734 // Move
735 if ( bbp_is_reply_move() ) {
736 $new_content = bbp_buffer_template_part( 'form', 'reply-move', false );
737
738 // Edit
739 } elseif ( bbp_is_reply_edit() ) {
740 $new_content = $bbp_shortcodes->display_reply_form();
741
742 // Lock the reply from other edits
743 bbp_set_post_lock( bbp_get_reply_id() );
744
745 // Single
746 } else {
747 $new_content = $bbp_shortcodes->display_reply( array( 'id' => get_the_ID() ) );
748 }
749
750 // Reset post
751 bbp_theme_compat_reset_post(
752 array(
753 'ID' => bbp_get_reply_id(),
754 'post_title' => bbp_get_reply_title(),
755 'post_author' => bbp_get_reply_author_id(),
756 'post_date' => bbp_get_empty_datetime(),
757 'post_content' => $new_content,
758 'post_type' => bbp_get_reply_post_type(),
759 'post_status' => bbp_get_reply_status(),
760 'is_single' => true,
761 'comment_status' => 'closed'
762 )
763 );
764
765 /** Views *************************************************************/
766
767 } elseif ( bbp_is_single_view() ) {
768
769 // Reset post
770 bbp_theme_compat_reset_post(
771 array(
772 'ID' => 0,
773 'post_title' => bbp_get_view_title(),
774 'post_author' => 0,
775 'post_date' => bbp_get_empty_datetime(),
776 'post_content' => $bbp_shortcodes->display_view( array( 'id' => get_query_var( bbp_get_view_rewrite_id() ) ) ),
777 'post_type' => '',
778 'post_status' => bbp_get_public_status_id(),
779 'is_archive' => true,
780 'comment_status' => 'closed'
781 )
782 );
783
784 /** Search ************************************************************/
785
786 } elseif ( bbp_is_search() ) {
787
788 // Reset post
789 bbp_theme_compat_reset_post(
790 array(
791 'ID' => 0,
792 'post_title' => bbp_get_search_title(),
793 'post_author' => 0,
794 'post_date' => bbp_get_empty_datetime(),
795 'post_content' => $bbp_shortcodes->display_search( array( 'search' => get_query_var( bbp_get_search_rewrite_id() ) ) ),
796 'post_type' => '',
797 'post_status' => bbp_get_public_status_id(),
798 'is_archive' => true,
799 'comment_status' => 'closed'
800 )
801 );
802
803 /** Topic Tags ********************************************************/
804
805 // Topic Tag Edit
806 } elseif ( bbp_is_topic_tag_edit() || bbp_is_topic_tag() ) {
807
808 // Stash the current term in a new var
809 set_query_var( 'bbp_topic_tag', get_query_var( 'term' ) );
810
811 // Show topics of tag
812 if ( bbp_is_topic_tag() ) {
813 $new_content = $bbp_shortcodes->display_topics_of_tag( array( 'id' => bbp_get_topic_tag_id() ) );
814
815 // Edit topic tag
816 } elseif ( bbp_is_topic_tag_edit() ) {
817 $new_content = $bbp_shortcodes->display_topic_tag_form();
818 }
819
820 // Reset the post with our new title
821 bbp_theme_compat_reset_post(
822 array(
823 'ID' => 0,
824 'post_author' => 0,
825 'post_date' => bbp_get_empty_datetime(),
826 'post_content' => $new_content,
827 'post_type' => '',
828 /* translators: %s: Topic tag name */
829 'post_title' => sprintf( esc_html__( 'Topic Tag: %s', 'bbpress' ), bbp_get_topic_tag_name() ),
830 'post_status' => bbp_get_public_status_id(),
831 'is_tax' => true,
832 'is_archive' => true,
833 'comment_status' => 'closed'
834 )
835 );
836 }
837
838 /**
839 * Bail if the template already matches a bbPress template. This includes
840 * archive-* and single-* WordPress post_type matches (allowing
841 * themes to use the expected format) as well as all bbPress-specific
842 * template files for users, topics, forums, etc...
843 *
844 * We do this after the above checks to prevent incorrect 404 body classes
845 * and header statuses, as well as to set the post global as needed.
846 *
847 * @see https://bbpress.trac.wordpress.org/ticket/1478/
848 */
849 if ( bbp_is_template_included() ) {
850 return $template;
851
852 /**
853 * If we are relying on the built-in theme compatibility API to load
854 * the proper content, we need to intercept the_content, replace the
855 * output, and display ours instead.
856 *
857 * To do this, we first remove all filters from 'the_content' and hook
858 * our own function into it, which runs a series of checks to determine
859 * the context, and then uses the built in shortcodes to output the
860 * correct results from inside an output buffer.
861 *
862 * Uses bbp_get_theme_compat_templates() to provide fall-backs that
863 * should be coded without superfluous mark-up and logic (prev/next
864 * navigation, comments, date/time, etc...)
865 *
866 * Hook into the 'bbp_get_bbpress_template' to override the array of
867 * possible templates, or 'bbp_bbpress_template' to override the result.
868 */
869 } elseif ( bbp_is_theme_compat_active() ) {
870 bbp_remove_all_filters( 'the_content' );
871
872 // Block themes
873 if ( wp_is_block_theme() ) {
874 $template = bbp_get_theme_canvas_template();
875
876 // Non-block themes
877 } else {
878 $template = bbp_get_theme_compat_templates();
879 }
880 }
881
882 // Filter & return
883 return apply_filters( 'bbp_template_include_theme_compat', $template );
884 }
885
886 /** Helpers *******************************************************************/
887
888 /**
889 * Remove the canonical redirect to allow pretty pagination
890 *
891 * @since 2.0.0 bbPress (r2628)
892 *
893 * @param string $redirect_url Redirect url
894 *
895 * @return bool|string False if it's a topic/forum and their first page,
896 * otherwise the redirect url
897 */
898 function bbp_redirect_canonical( $redirect_url ) {
899
900 // Canonical is for the beautiful
901 if ( bbp_use_pretty_urls() ) {
902
903 // If viewing beyond page 1 of several
904 if ( 1 < bbp_get_paged() ) {
905
906 // Only on single topics...
907 if ( bbp_is_single_topic() ) {
908 $redirect_url = false;
909
910 // ...and single forums...
911 } elseif ( bbp_is_single_forum() ) {
912 $redirect_url = false;
913
914 // ...and single replies...
915 } elseif ( bbp_is_single_reply() ) {
916 $redirect_url = false;
917
918 // ...and any single anything else...
919 //
920 // @todo - Find a more accurate way to disable paged canonicals for
921 // paged shortcode usage within other posts.
922 } elseif ( is_page() || is_singular() ) {
923 $redirect_url = false;
924 }
925
926 // If editing a topic
927 } elseif ( bbp_is_topic_edit() ) {
928 $redirect_url = false;
929
930 // If editing a reply
931 } elseif ( bbp_is_reply_edit() ) {
932 $redirect_url = false;
933 }
934 }
935
936 return $redirect_url;
937 }
938
939 /** Filters *******************************************************************/
940
941 /**
942 * Removes all filters from a WordPress filter, and stashes them in the $bbp
943 * global in the event they need to be restored later.
944 *
945 * @since 2.0.0 bbPress (r3251)
946 *
947 * @global WP_filter $wp_filter
948 * @global array $merged_filters
949 * @param string $tag
950 * @param int $priority
951 * @return bool
952 */
953 function bbp_remove_all_filters( $tag, $priority = false ) {
954 global $wp_filter, $merged_filters;
955
956 $bbp = bbpress();
957
958 // Filters exist
959 if ( isset( $wp_filter[ $tag ] ) ) {
960
961 // Filters exist in this priority
962 if ( ! empty( $priority ) && isset( $wp_filter[ $tag ][ $priority ] ) ) {
963
964 // Store filters in a backup
965 $bbp->filters->wp_filter[ $tag ][ $priority ] = $wp_filter[ $tag ][ $priority ];
966
967 // Unset the filters
968 unset( $wp_filter[ $tag ][ $priority ] );
969
970 // Priority is empty
971 } else {
972
973 // Store filters in a backup
974 $bbp->filters->wp_filter[ $tag ] = $wp_filter[ $tag ];
975
976 // Unset the filters
977 unset( $wp_filter[ $tag ] );
978 }
979 }
980
981 // Check merged filters
982 if ( isset( $merged_filters[ $tag ] ) ) {
983
984 // Store filters in a backup
985 $bbp->filters->merged_filters[ $tag ] = $merged_filters[ $tag ];
986
987 // Unset the filters
988 unset( $merged_filters[ $tag ] );
989 }
990
991 return true;
992 }
993
994 /**
995 * Restores filters from the $bbp global that were removed using
996 * bbp_remove_all_filters()
997 *
998 * @since 2.0.0 bbPress (r3251)
999 *
1000 * @global WP_filter $wp_filter
1001 * @global array $merged_filters
1002 * @param string $tag
1003 * @param int $priority
1004 * @return bool
1005 */
1006 function bbp_restore_all_filters( $tag, $priority = false ) {
1007 global $wp_filter, $merged_filters;
1008
1009 // phpcs:disable WordPress.WP.GlobalVariablesOverride.Prohibited
1010
1011 $bbp = bbpress();
1012
1013 // Filters exist
1014 if ( isset( $bbp->filters->wp_filter[ $tag ] ) ) {
1015
1016 // Filters exist in this priority
1017 if ( ! empty( $priority ) && isset( $bbp->filters->wp_filter[ $tag ][ $priority ] ) ) {
1018
1019 // Store filters in a backup
1020 $wp_filter[ $tag ][ $priority ] = $bbp->filters->wp_filter[ $tag ][ $priority ];
1021
1022 // Unset the filters
1023 unset( $bbp->filters->wp_filter[ $tag ][ $priority ] );
1024
1025 // Priority is empty
1026 } else {
1027
1028 // Store filters in a backup
1029 $wp_filter[ $tag ] = $bbp->filters->wp_filter[ $tag ];
1030
1031 // Unset the filters
1032 unset( $bbp->filters->wp_filter[ $tag ] );
1033 }
1034 }
1035
1036 // Check merged filters
1037 if ( isset( $bbp->filters->merged_filters[ $tag ] ) ) {
1038
1039 // Store filters in a backup
1040 $merged_filters[ $tag ] = $bbp->filters->merged_filters[ $tag ];
1041
1042 // Unset the filters
1043 unset( $bbp->filters->merged_filters[ $tag ] );
1044 }
1045
1046 return true;
1047 }
1048
1049 /**
1050 * Force comments_status to 'closed' for bbPress post types
1051 *
1052 * @since 2.1.0 bbPress (r3589)
1053 *
1054 * @param bool $open True if open, false if closed
1055 * @param int $post_id ID of the post to check
1056 * @return bool True if open, false if closed
1057 */
1058 function bbp_force_comment_status( $open = false, $post_id = 0 ) {
1059
1060 // Default return value is what is passed in $open
1061 $retval = (bool) $open;
1062
1063 // Get the post type of the post ID
1064 $post_type = get_post_type( $post_id );
1065
1066 // Only force for bbPress post types
1067 if ( in_array( $post_type, bbp_get_post_types(), true ) ) {
1068 $retval = false;
1069 }
1070
1071 // Filter & return
1072 return (bool) apply_filters( 'bbp_force_comment_status', $retval, $open, $post_id, $post_type );
1073 }
1074
1075 /**
1076 * Remove "prev" and "next" relational links from <head> on bbPress pages.
1077 *
1078 * WordPress automatically generates these relational links to the current
1079 * page, but bbPress does not use these links, nor would they work the same.
1080 *
1081 * In this function, we remove these links when on a bbPress page. This also
1082 * prevents additional, unnecessary queries from running.
1083 *
1084 * @since 2.6.0 bbPress (r7071)
1085 */
1086 function bbp_remove_adjacent_posts() {
1087
1088 // Bail if not a bbPress page
1089 if ( ! is_bbpress() ) {
1090 return;
1091 }
1092
1093 // Remove the WordPress core action for adjacent posts
1094 remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10 );
1095 }
1096