PluginProbe
bbPress / 2.6.6
bbPress v2.6.6
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 2.2.2 All 71 releases
bbpress / includes / core / theme-compat.php

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

1,061 lines 29.9 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 // Set the $post global
450 $post = new WP_Post( (object) $dummy );
451
452 // Copy the new post global into the main $wp_query
453 $wp_query->post = $post;
454 $wp_query->posts = array( $post );
455
456 // Prevent comments form from appearing
457 $wp_query->post_count = 1;
458 $wp_query->is_404 = $dummy['is_404'];
459 $wp_query->is_page = $dummy['is_page'];
460 $wp_query->is_single = $dummy['is_single'];
461 $wp_query->is_archive = $dummy['is_archive'];
462 $wp_query->is_tax = $dummy['is_tax'];
463
464 // Reset is_singular based on page/single args
465 // https://bbpress.trac.wordpress.org/ticket/2545
466 $wp_query->is_singular = $wp_query->is_single;
467
468 // Clean up the dummy post
469 unset( $dummy );
470
471 // If we are resetting a post, we are in theme compat
472 bbp_set_theme_compat_active( true );
473 }
474
475 /**
476 * Reset main query vars and filter 'the_content' to output a bbPress
477 * template part as needed.
478 *
479 * @since 2.0.0 bbPress (r3032)
480 *
481 * @param string $template
482 */
483 function bbp_template_include_theme_compat( $template = '' ) {
484
485 /**
486 * Bail if a root template was already found. This prevents unintended
487 * recursive filtering of 'the_content'.
488 *
489 * @link https://bbpress.trac.wordpress.org/ticket/2429
490 */
491 if ( bbp_is_template_included() ) {
492 return $template;
493 }
494
495 /**
496 * If BuddyPress is activated at a network level, the action order is
497 * reversed, which causes the template integration to fail. If we're looking
498 * at a BuddyPress page here, bail to prevent the extra processing.
499 *
500 * This is a bit more brute-force than is probably necessary, but gets the
501 * job done while we work towards something more elegant.
502 */
503 if ( function_exists( 'is_buddypress' ) && is_buddypress() ) {
504 return $template;
505 }
506
507 // Define local variable(s)
508 $bbp_shortcodes = bbpress()->shortcodes;
509
510 // Bail if shortcodes are unset somehow
511 if ( ! is_a( $bbp_shortcodes, 'BBP_Shortcodes' ) ) {
512 return $template;
513 }
514
515 /** Users *************************************************************/
516
517 if ( bbp_is_single_user_edit() || bbp_is_single_user() ) {
518
519 // Reset post
520 bbp_theme_compat_reset_post( array(
521 'ID' => 0,
522 'post_author' => 0,
523 'post_date' => bbp_get_empty_datetime(),
524 'post_content' => bbp_buffer_template_part( 'content', 'single-user', false ),
525 'post_type' => '',
526 'post_title' => bbp_get_displayed_user_field( 'display_name' ),
527 'post_status' => bbp_get_public_status_id(),
528 'is_archive' => false,
529 'comment_status' => 'closed'
530 ) );
531
532 /** Forums ************************************************************/
533
534 // Forum archive
535 } elseif ( bbp_is_forum_archive() ) {
536
537 // Page exists where this archive should be
538 $page = bbp_get_page_by_path( bbp_get_root_slug() );
539
540 // Should we replace the content...
541 if ( empty( $page->post_content ) ) {
542
543 // Use the topics archive
544 if ( 'topics' === bbp_show_on_root() ) {
545 $new_content = $bbp_shortcodes->display_topic_index();
546
547 // No page so show the archive
548 } else {
549 $new_content = $bbp_shortcodes->display_forum_index();
550 }
551
552 // ...or use the existing page content?
553 } else {
554 $new_content = apply_filters( 'the_content', $page->post_content );
555 }
556
557 // Should we replace the title...
558 if ( empty( $page->post_title ) ) {
559
560 // Use the topics archive
561 if ( 'topics' === bbp_show_on_root() ) {
562 $new_title = bbp_get_topic_archive_title();
563
564 // No page so show the archive
565 } else {
566 $new_title = bbp_get_forum_archive_title();
567 }
568
569 // ...or use the existing page title?
570 } else {
571 $new_title = apply_filters( 'the_title', $page->post_title );
572 }
573
574 // Reset post
575 bbp_theme_compat_reset_post( array(
576 'ID' => ! empty( $page->ID ) ? $page->ID : 0,
577 'post_title' => $new_title,
578 'post_author' => 0,
579 'post_date' => bbp_get_empty_datetime(),
580 'post_content' => $new_content,
581 'post_type' => bbp_get_forum_post_type(),
582 'post_status' => bbp_get_public_status_id(),
583 'is_archive' => true,
584 'comment_status' => 'closed'
585 ) );
586
587 // Single Forum
588 } elseif ( bbp_is_forum_edit() ) {
589
590 // Reset post
591 bbp_theme_compat_reset_post( array(
592 'ID' => bbp_get_forum_id(),
593 'post_title' => bbp_get_forum_title(),
594 'post_author' => bbp_get_forum_author_id(),
595 'post_date' => bbp_get_empty_datetime(),
596 'post_content' => $bbp_shortcodes->display_forum_form(),
597 'post_type' => bbp_get_forum_post_type(),
598 'post_status' => bbp_get_forum_visibility(),
599 'is_single' => true,
600 'comment_status' => 'closed'
601 ) );
602
603 // Lock the forum from other edits
604 bbp_set_post_lock( bbp_get_forum_id() );
605
606 } elseif ( bbp_is_single_forum() ) {
607
608 // Reset post
609 bbp_theme_compat_reset_post( array(
610 'ID' => bbp_get_forum_id(),
611 'post_title' => bbp_get_forum_title(),
612 'post_author' => bbp_get_forum_author_id(),
613 'post_date' => bbp_get_empty_datetime(),
614 'post_content' => $bbp_shortcodes->display_forum( array( 'id' => bbp_get_forum_id() ) ),
615 'post_type' => bbp_get_forum_post_type(),
616 'post_status' => bbp_get_forum_visibility(),
617 'is_single' => true,
618 'comment_status' => 'closed'
619 ) );
620
621 /** Topics ************************************************************/
622
623 // Topic archive
624 } elseif ( bbp_is_topic_archive() ) {
625
626 // Page exists where this archive should be
627 $page = bbp_get_page_by_path( bbp_get_topic_archive_slug() );
628
629 // Should we replace the content...
630 if ( empty( $page->post_content ) ) {
631 $new_content = $bbp_shortcodes->display_topic_index();
632
633 // ...or use the existing page content?
634 } else {
635 $new_content = apply_filters( 'the_content', $page->post_content );
636 }
637
638 // Should we replace the title...
639 if ( empty( $page->post_title ) ) {
640 $new_title = bbp_get_topic_archive_title();
641
642 // ...or use the existing page title?
643 } else {
644 $new_title = apply_filters( 'the_title', $page->post_title );
645 }
646
647 // Reset post
648 bbp_theme_compat_reset_post( array(
649 'ID' => ! empty( $page->ID ) ? $page->ID : 0,
650 'post_title' => bbp_get_topic_archive_title(),
651 'post_author' => 0,
652 'post_date' => bbp_get_empty_datetime(),
653 'post_content' => $new_content,
654 'post_type' => bbp_get_topic_post_type(),
655 'post_status' => bbp_get_public_status_id(),
656 'is_archive' => true,
657 'comment_status' => 'closed'
658 ) );
659
660 // Single Topic
661 } elseif ( bbp_is_topic_edit() || bbp_is_single_topic() ) {
662
663 // Split
664 if ( bbp_is_topic_split() ) {
665 $new_content = bbp_buffer_template_part( 'form', 'topic-split', false );
666
667 // Merge
668 } elseif ( bbp_is_topic_merge() ) {
669 $new_content = bbp_buffer_template_part( 'form', 'topic-merge', false );
670
671 // Edit
672 } elseif ( bbp_is_topic_edit() ) {
673 $new_content = $bbp_shortcodes->display_topic_form();
674
675 // Lock the topic from other edits
676 bbp_set_post_lock( bbp_get_topic_id() );
677
678 // Single
679 } else {
680 $new_content = $bbp_shortcodes->display_topic( array( 'id' => bbp_get_topic_id() ) );
681 }
682
683 // Reset post
684 bbp_theme_compat_reset_post( array(
685 'ID' => bbp_get_topic_id(),
686 'post_title' => bbp_get_topic_title(),
687 'post_author' => bbp_get_topic_author_id(),
688 'post_date' => bbp_get_empty_datetime(),
689 'post_content' => $new_content,
690 'post_type' => bbp_get_topic_post_type(),
691 'post_status' => bbp_get_topic_status(),
692 'is_single' => true,
693 'comment_status' => 'closed'
694 ) );
695
696 /** Replies ***********************************************************/
697
698 // Reply archive
699 } elseif ( is_post_type_archive( bbp_get_reply_post_type() ) ) {
700
701 // Reset post
702 bbp_theme_compat_reset_post( array(
703 'ID' => 0,
704 'post_title' => esc_html__( 'Replies', 'bbpress' ),
705 'post_author' => 0,
706 'post_date' => bbp_get_empty_datetime(),
707 'post_content' => $bbp_shortcodes->display_reply_index(),
708 'post_type' => bbp_get_reply_post_type(),
709 'post_status' => bbp_get_public_status_id(),
710 'is_archive' => true,
711 'comment_status' => 'closed'
712 ) );
713
714 // Single Reply
715 } elseif ( bbp_is_reply_edit() || bbp_is_single_reply() ) {
716
717 // Move
718 if ( bbp_is_reply_move() ) {
719 $new_content = bbp_buffer_template_part( 'form', 'reply-move', false );
720
721 // Edit
722 } elseif ( bbp_is_reply_edit() ) {
723 $new_content = $bbp_shortcodes->display_reply_form();
724
725 // Lock the reply from other edits
726 bbp_set_post_lock( bbp_get_reply_id() );
727
728 // Single
729 } else {
730 $new_content = $bbp_shortcodes->display_reply( array( 'id' => get_the_ID() ) );
731 }
732
733 // Reset post
734 bbp_theme_compat_reset_post( array(
735 'ID' => bbp_get_reply_id(),
736 'post_title' => bbp_get_reply_title(),
737 'post_author' => bbp_get_reply_author_id(),
738 'post_date' => bbp_get_empty_datetime(),
739 'post_content' => $new_content,
740 'post_type' => bbp_get_reply_post_type(),
741 'post_status' => bbp_get_reply_status(),
742 'is_single' => true,
743 'comment_status' => 'closed'
744 ) );
745
746 /** Views *************************************************************/
747
748 } elseif ( bbp_is_single_view() ) {
749
750 // Reset post
751 bbp_theme_compat_reset_post( array(
752 'ID' => 0,
753 'post_title' => bbp_get_view_title(),
754 'post_author' => 0,
755 'post_date' => bbp_get_empty_datetime(),
756 'post_content' => $bbp_shortcodes->display_view( array( 'id' => get_query_var( bbp_get_view_rewrite_id() ) ) ),
757 'post_type' => '',
758 'post_status' => bbp_get_public_status_id(),
759 'is_archive' => true,
760 'comment_status' => 'closed'
761 ) );
762
763 /** Search ************************************************************/
764
765 } elseif ( bbp_is_search() ) {
766
767 // Reset post
768 bbp_theme_compat_reset_post( array(
769 'ID' => 0,
770 'post_title' => bbp_get_search_title(),
771 'post_author' => 0,
772 'post_date' => bbp_get_empty_datetime(),
773 'post_content' => $bbp_shortcodes->display_search( array( 'search' => get_query_var( bbp_get_search_rewrite_id() ) ) ),
774 'post_type' => '',
775 'post_status' => bbp_get_public_status_id(),
776 'is_archive' => true,
777 'comment_status' => 'closed'
778 ) );
779
780 /** Topic Tags ********************************************************/
781
782 // Topic Tag Edit
783 } elseif ( bbp_is_topic_tag_edit() || bbp_is_topic_tag() ) {
784
785 // Stash the current term in a new var
786 set_query_var( 'bbp_topic_tag', get_query_var( 'term' ) );
787
788 // Show topics of tag
789 if ( bbp_is_topic_tag() ) {
790 $new_content = $bbp_shortcodes->display_topics_of_tag( array( 'id' => bbp_get_topic_tag_id() ) );
791
792 // Edit topic tag
793 } elseif ( bbp_is_topic_tag_edit() ) {
794 $new_content = $bbp_shortcodes->display_topic_tag_form();
795 }
796
797 // Reset the post with our new title
798 bbp_theme_compat_reset_post( array(
799 'ID' => 0,
800 'post_author' => 0,
801 'post_date' => bbp_get_empty_datetime(),
802 'post_content' => $new_content,
803 'post_type' => '',
804 'post_title' => sprintf( esc_html__( 'Topic Tag: %s', 'bbpress' ), bbp_get_topic_tag_name() ),
805 'post_status' => bbp_get_public_status_id(),
806 'is_tax' => true,
807 'is_archive' => true,
808 'comment_status' => 'closed'
809 ) );
810 }
811
812 /**
813 * Bail if the template already matches a bbPress template. This includes
814 * archive-* and single-* WordPress post_type matches (allowing
815 * themes to use the expected format) as well as all bbPress-specific
816 * template files for users, topics, forums, etc...
817 *
818 * We do this after the above checks to prevent incorrect 404 body classes
819 * and header statuses, as well as to set the post global as needed.
820 *
821 * @see https://bbpress.trac.wordpress.org/ticket/1478/
822 */
823 if ( bbp_is_template_included() ) {
824 return $template;
825
826 /**
827 * If we are relying on the built-in theme compatibility API to load
828 * the proper content, we need to intercept the_content, replace the
829 * output, and display ours instead.
830 *
831 * To do this, we first remove all filters from 'the_content' and hook
832 * our own function into it, which runs a series of checks to determine
833 * the context, and then uses the built in shortcodes to output the
834 * correct results from inside an output buffer.
835 *
836 * Uses bbp_get_theme_compat_templates() to provide fall-backs that
837 * should be coded without superfluous mark-up and logic (prev/next
838 * navigation, comments, date/time, etc...)
839 *
840 * Hook into the 'bbp_get_bbpress_template' to override the array of
841 * possible templates, or 'bbp_bbpress_template' to override the result.
842 */
843 } elseif ( bbp_is_theme_compat_active() ) {
844 bbp_remove_all_filters( 'the_content' );
845
846 $template = bbp_get_theme_compat_templates();
847 }
848
849 // Filter & return
850 return apply_filters( 'bbp_template_include_theme_compat', $template );
851 }
852
853 /** Helpers *******************************************************************/
854
855 /**
856 * Remove the canonical redirect to allow pretty pagination
857 *
858 * @since 2.0.0 bbPress (r2628)
859 *
860 * @param string $redirect_url Redirect url
861 *
862 * @return bool|string False if it's a topic/forum and their first page,
863 * otherwise the redirect url
864 */
865 function bbp_redirect_canonical( $redirect_url ) {
866
867 // Canonical is for the beautiful
868 if ( bbp_use_pretty_urls() ) {
869
870 // If viewing beyond page 1 of several
871 if ( 1 < bbp_get_paged() ) {
872
873 // Only on single topics...
874 if ( bbp_is_single_topic() ) {
875 $redirect_url = false;
876
877 // ...and single forums...
878 } elseif ( bbp_is_single_forum() ) {
879 $redirect_url = false;
880
881 // ...and single replies...
882 } elseif ( bbp_is_single_reply() ) {
883 $redirect_url = false;
884
885 // ...and any single anything else...
886 //
887 // @todo - Find a more accurate way to disable paged canonicals for
888 // paged shortcode usage within other posts.
889 } elseif ( is_page() || is_singular() ) {
890 $redirect_url = false;
891 }
892
893 // If editing a topic
894 } elseif ( bbp_is_topic_edit() ) {
895 $redirect_url = false;
896
897 // If editing a reply
898 } elseif ( bbp_is_reply_edit() ) {
899 $redirect_url = false;
900 }
901 }
902
903 return $redirect_url;
904 }
905
906 /** Filters *******************************************************************/
907
908 /**
909 * Removes all filters from a WordPress filter, and stashes them in the $bbp
910 * global in the event they need to be restored later.
911 *
912 * @since 2.0.0 bbPress (r3251)
913 *
914 * @global WP_filter $wp_filter
915 * @global array $merged_filters
916 * @param string $tag
917 * @param int $priority
918 * @return bool
919 */
920 function bbp_remove_all_filters( $tag, $priority = false ) {
921 global $wp_filter, $merged_filters;
922
923 $bbp = bbpress();
924
925 // Filters exist
926 if ( isset( $wp_filter[ $tag ] ) ) {
927
928 // Filters exist in this priority
929 if ( ! empty( $priority ) && isset( $wp_filter[ $tag ][ $priority ] ) ) {
930
931 // Store filters in a backup
932 $bbp->filters->wp_filter[ $tag ][ $priority ] = $wp_filter[ $tag ][ $priority ];
933
934 // Unset the filters
935 unset( $wp_filter[ $tag ][ $priority ] );
936
937 // Priority is empty
938 } else {
939
940 // Store filters in a backup
941 $bbp->filters->wp_filter[ $tag ] = $wp_filter[ $tag ];
942
943 // Unset the filters
944 unset( $wp_filter[ $tag ] );
945 }
946 }
947
948 // Check merged filters
949 if ( isset( $merged_filters[ $tag ] ) ) {
950
951 // Store filters in a backup
952 $bbp->filters->merged_filters[ $tag ] = $merged_filters[ $tag ];
953
954 // Unset the filters
955 unset( $merged_filters[ $tag ] );
956 }
957
958 return true;
959 }
960
961 /**
962 * Restores filters from the $bbp global that were removed using
963 * bbp_remove_all_filters()
964 *
965 * @since 2.0.0 bbPress (r3251)
966 *
967 * @global WP_filter $wp_filter
968 * @global array $merged_filters
969 * @param string $tag
970 * @param int $priority
971 * @return bool
972 */
973 function bbp_restore_all_filters( $tag, $priority = false ) {
974 global $wp_filter, $merged_filters;
975
976 $bbp = bbpress();
977
978 // Filters exist
979 if ( isset( $bbp->filters->wp_filter[ $tag ] ) ) {
980
981 // Filters exist in this priority
982 if ( ! empty( $priority ) && isset( $bbp->filters->wp_filter[ $tag ][ $priority ] ) ) {
983
984 // Store filters in a backup
985 $wp_filter[ $tag ][ $priority ] = $bbp->filters->wp_filter[ $tag ][ $priority ];
986
987 // Unset the filters
988 unset( $bbp->filters->wp_filter[ $tag ][ $priority ] );
989
990 // Priority is empty
991 } else {
992
993 // Store filters in a backup
994 $wp_filter[ $tag ] = $bbp->filters->wp_filter[ $tag ];
995
996 // Unset the filters
997 unset( $bbp->filters->wp_filter[ $tag ] );
998 }
999 }
1000
1001 // Check merged filters
1002 if ( isset( $bbp->filters->merged_filters[ $tag ] ) ) {
1003
1004 // Store filters in a backup
1005 $merged_filters[ $tag ] = $bbp->filters->merged_filters[ $tag ];
1006
1007 // Unset the filters
1008 unset( $bbp->filters->merged_filters[ $tag ] );
1009 }
1010
1011 return true;
1012 }
1013
1014 /**
1015 * Force comments_status to 'closed' for bbPress post types
1016 *
1017 * @since 2.1.0 bbPress (r3589)
1018 *
1019 * @param bool $open True if open, false if closed
1020 * @param int $post_id ID of the post to check
1021 * @return bool True if open, false if closed
1022 */
1023 function bbp_force_comment_status( $open = false, $post_id = 0 ) {
1024
1025 // Default return value is what is passed in $open
1026 $retval = (bool) $open;
1027
1028 // Get the post type of the post ID
1029 $post_type = get_post_type( $post_id );
1030
1031 // Only force for bbPress post types
1032 if ( in_array( $post_type, bbp_get_post_types(), true ) ) {
1033 $retval = false;
1034 }
1035
1036 // Filter & return
1037 return (bool) apply_filters( 'bbp_force_comment_status', $retval, $open, $post_id, $post_type );
1038 }
1039
1040 /**
1041 * Remove "prev" and "next" relational links from <head> on bbPress pages.
1042 *
1043 * WordPress automatically generates these relational links to the current
1044 * page, but bbPress does not use these links, nor would they work the same.
1045 *
1046 * In this function, we remove these links when on a bbPress page. This also
1047 * prevents additional, unnecessary queries from running.
1048 *
1049 * @since 2.6.0 bbPress (r7071)
1050 */
1051 function bbp_remove_adjacent_posts() {
1052
1053 // Bail if not a bbPress page
1054 if ( ! is_bbpress() ) {
1055 return;
1056 }
1057
1058 // Remove the WordPress core action for adjacent posts
1059 remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10 );
1060 }
1061