PageRenderTime 68ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/bbpress/includes/core/theme-compat.php

https://github.com/bfay/maniacal-kitten
PHP | 1085 lines | 460 code | 193 blank | 432 comment | 52 complexity | 809800137e9950011ad6944d36fd0848 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, AGPL-1.0, LGPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. * bbPress Core Theme Compatibility
  4. *
  5. * @package bbPress
  6. * @subpackage ThemeCompatibility
  7. */
  8. // Exit if accessed directly
  9. if ( !defined( 'ABSPATH' ) ) exit;
  10. /** Theme Compat **************************************************************/
  11. /**
  12. * What follows is an attempt at intercepting the natural page load process
  13. * to replace the_content() with the appropriate bbPress content.
  14. *
  15. * To do this, bbPress does several direct manipulations of global variables
  16. * and forces them to do what they are not supposed to be doing.
  17. *
  18. * Don't try anything you're about to witness here, at home. Ever.
  19. */
  20. /** Base Class ****************************************************************/
  21. /**
  22. * Theme Compatibility base class
  23. *
  24. * This is only intended to be extended, and is included here as a basic guide
  25. * for future Theme Packs to use. @link BBP_Twenty_Ten is a good example of
  26. * extending this class, as is @link bbp_setup_theme_compat()
  27. *
  28. * @since bbPress (r3506)
  29. */
  30. class BBP_Theme_Compat {
  31. /**
  32. * Should be like:
  33. *
  34. * array(
  35. * 'id' => ID of the theme (should be unique)
  36. * 'name' => Name of the theme (should match style.css)
  37. * 'version' => Theme version for cache busting scripts and styling
  38. * 'dir' => Path to theme
  39. * 'url' => URL to theme
  40. * );
  41. * @var array
  42. */
  43. private $_data = array();
  44. /**
  45. * Pass the $properties to the object on creation.
  46. *
  47. * @since bbPress (r3926)
  48. * @param array $properties
  49. */
  50. public function __construct( Array $properties = array() ) {
  51. $this->_data = $properties;
  52. }
  53. /**
  54. * Set a theme's property.
  55. *
  56. * @since bbPress (r3926)
  57. * @param string $property
  58. * @param mixed $value
  59. * @return mixed
  60. */
  61. public function __set( $property, $value ) {
  62. return $this->_data[$property] = $value;
  63. }
  64. /**
  65. * Get a theme's property.
  66. *
  67. * @since bbPress (r3926)
  68. * @param string $property
  69. * @param mixed $value
  70. * @return mixed
  71. */
  72. public function __get( $property ) {
  73. return array_key_exists( $property, $this->_data ) ? $this->_data[$property] : '';
  74. }
  75. }
  76. /** Functions *****************************************************************/
  77. /**
  78. * Setup the default theme compat theme
  79. *
  80. * @since bbPress (r3311)
  81. * @param BBP_Theme_Compat $theme
  82. */
  83. function bbp_setup_theme_compat( $theme = '' ) {
  84. $bbp = bbpress();
  85. // Make sure theme package is available, set to default if not
  86. if ( ! isset( $bbp->theme_compat->packages[$theme] ) || ! is_a( $bbp->theme_compat->packages[$theme], 'BBP_Theme_Compat' ) ) {
  87. $theme = 'default';
  88. }
  89. // Set the active theme compat theme
  90. $bbp->theme_compat->theme = $bbp->theme_compat->packages[$theme];
  91. }
  92. /**
  93. * Gets the name of the bbPress compatable theme used, in the event the
  94. * currently active WordPress theme does not explicitly support bbPress.
  95. * This can be filtered or set manually. Tricky theme authors can override the
  96. * default and include their own bbPress compatibility layers for their themes.
  97. *
  98. * @since bbPress (r3506)
  99. * @uses apply_filters()
  100. * @return string
  101. */
  102. function bbp_get_theme_compat_id() {
  103. return apply_filters( 'bbp_get_theme_compat_id', bbpress()->theme_compat->theme->id );
  104. }
  105. /**
  106. * Gets the name of the bbPress compatable theme used, in the event the
  107. * currently active WordPress theme does not explicitly support bbPress.
  108. * This can be filtered or set manually. Tricky theme authors can override the
  109. * default and include their own bbPress compatibility layers for their themes.
  110. *
  111. * @since bbPress (r3506)
  112. * @uses apply_filters()
  113. * @return string
  114. */
  115. function bbp_get_theme_compat_name() {
  116. return apply_filters( 'bbp_get_theme_compat_name', bbpress()->theme_compat->theme->name );
  117. }
  118. /**
  119. * Gets the version of the bbPress compatable theme used, in the event the
  120. * currently active WordPress theme does not explicitly support bbPress.
  121. * This can be filtered or set manually. Tricky theme authors can override the
  122. * default and include their own bbPress compatibility layers for their themes.
  123. *
  124. * @since bbPress (r3506)
  125. * @uses apply_filters()
  126. * @return string
  127. */
  128. function bbp_get_theme_compat_version() {
  129. return apply_filters( 'bbp_get_theme_compat_version', bbpress()->theme_compat->theme->version );
  130. }
  131. /**
  132. * Gets the bbPress compatable theme used in the event the currently active
  133. * WordPress theme does not explicitly support bbPress. This can be filtered,
  134. * or set manually. Tricky theme authors can override the default and include
  135. * their own bbPress compatibility layers for their themes.
  136. *
  137. * @since bbPress (r3032)
  138. * @uses apply_filters()
  139. * @return string
  140. */
  141. function bbp_get_theme_compat_dir() {
  142. return apply_filters( 'bbp_get_theme_compat_dir', bbpress()->theme_compat->theme->dir );
  143. }
  144. /**
  145. * Gets the bbPress compatable theme used in the event the currently active
  146. * WordPress theme does not explicitly support bbPress. This can be filtered,
  147. * or set manually. Tricky theme authors can override the default and include
  148. * their own bbPress compatibility layers for their themes.
  149. *
  150. * @since bbPress (r3032)
  151. * @uses apply_filters()
  152. * @return string
  153. */
  154. function bbp_get_theme_compat_url() {
  155. return apply_filters( 'bbp_get_theme_compat_url', bbpress()->theme_compat->theme->url );
  156. }
  157. /**
  158. * Gets true/false if page is currently inside theme compatibility
  159. *
  160. * @since bbPress (r3265)
  161. * @return bool
  162. */
  163. function bbp_is_theme_compat_active() {
  164. $bbp = bbpress();
  165. if ( empty( $bbp->theme_compat->active ) )
  166. return false;
  167. return $bbp->theme_compat->active;
  168. }
  169. /**
  170. * Sets true/false if page is currently inside theme compatibility
  171. *
  172. * @since bbPress (r3265)
  173. * @param bool $set
  174. * @return bool
  175. */
  176. function bbp_set_theme_compat_active( $set = true ) {
  177. bbpress()->theme_compat->active = $set;
  178. return (bool) bbpress()->theme_compat->active;
  179. }
  180. /**
  181. * Set the theme compat templates global
  182. *
  183. * Stash possible template files for the current query. Useful if plugins want
  184. * to override them, or see what files are being scanned for inclusion.
  185. *
  186. * @since bbPress (r3311)
  187. */
  188. function bbp_set_theme_compat_templates( $templates = array() ) {
  189. bbpress()->theme_compat->templates = $templates;
  190. return bbpress()->theme_compat->templates;
  191. }
  192. /**
  193. * Set the theme compat template global
  194. *
  195. * Stash the template file for the current query. Useful if plugins want
  196. * to override it, or see what file is being included.
  197. *
  198. * @since bbPress (r3311)
  199. */
  200. function bbp_set_theme_compat_template( $template = '' ) {
  201. bbpress()->theme_compat->template = $template;
  202. return bbpress()->theme_compat->template;
  203. }
  204. /**
  205. * Set the theme compat original_template global
  206. *
  207. * Stash the original template file for the current query. Useful for checking
  208. * if bbPress was able to find a more appropriate template.
  209. *
  210. * @since bbPress (r3926)
  211. */
  212. function bbp_set_theme_compat_original_template( $template = '' ) {
  213. bbpress()->theme_compat->original_template = $template;
  214. return bbpress()->theme_compat->original_template;
  215. }
  216. /**
  217. * Set the theme compat original_template global
  218. *
  219. * Stash the original template file for the current query. Useful for checking
  220. * if bbPress was able to find a more appropriate template.
  221. *
  222. * @since bbPress (r3926)
  223. */
  224. function bbp_is_theme_compat_original_template( $template = '' ) {
  225. $bbp = bbpress();
  226. if ( empty( $bbp->theme_compat->original_template ) )
  227. return false;
  228. return (bool) ( $bbp->theme_compat->original_template == $template );
  229. }
  230. /**
  231. * Register a new bbPress theme package to the active theme packages array
  232. *
  233. * @since bbPress (r3829)
  234. * @param array $theme
  235. */
  236. function bbp_register_theme_package( $theme = array(), $override = true ) {
  237. // Create new BBP_Theme_Compat object from the $theme array
  238. if ( is_array( $theme ) )
  239. $theme = new BBP_Theme_Compat( $theme );
  240. // Bail if $theme isn't a proper object
  241. if ( ! is_a( $theme, 'BBP_Theme_Compat' ) )
  242. return;
  243. // Load up bbPress
  244. $bbp = bbpress();
  245. // Only override if the flag is set and not previously registered
  246. if ( empty( $bbp->theme_compat->packages[$theme->id] ) || ( true === $override ) ) {
  247. $bbp->theme_compat->packages[$theme->id] = $theme;
  248. }
  249. }
  250. /**
  251. * This fun little function fills up some WordPress globals with dummy data to
  252. * stop your average page template from complaining about it missing.
  253. *
  254. * @since bbPress (r3108)
  255. * @global WP_Query $wp_query
  256. * @global object $post
  257. * @param array $args
  258. */
  259. function bbp_theme_compat_reset_post( $args = array() ) {
  260. global $wp_query, $post;
  261. // Default arguments
  262. $defaults = array(
  263. 'ID' => -9999,
  264. 'post_status' => bbp_get_public_status_id(),
  265. 'post_author' => 0,
  266. 'post_parent' => 0,
  267. 'post_type' => 'page',
  268. 'post_date' => 0,
  269. 'post_date_gmt' => 0,
  270. 'post_modified' => 0,
  271. 'post_modified_gmt' => 0,
  272. 'post_content' => '',
  273. 'post_title' => '',
  274. 'post_excerpt' => '',
  275. 'post_content_filtered' => '',
  276. 'post_mime_type' => '',
  277. 'post_password' => '',
  278. 'post_name' => '',
  279. 'guid' => '',
  280. 'menu_order' => 0,
  281. 'pinged' => '',
  282. 'to_ping' => '',
  283. 'ping_status' => '',
  284. 'comment_status' => 'closed',
  285. 'comment_count' => 0,
  286. 'is_404' => false,
  287. 'is_page' => false,
  288. 'is_single' => false,
  289. 'is_archive' => false,
  290. 'is_tax' => false,
  291. );
  292. // Switch defaults if post is set
  293. if ( isset( $wp_query->post ) ) {
  294. $defaults = array(
  295. 'ID' => $wp_query->post->ID,
  296. 'post_status' => $wp_query->post->post_status,
  297. 'post_author' => $wp_query->post->post_author,
  298. 'post_parent' => $wp_query->post->post_parent,
  299. 'post_type' => $wp_query->post->post_type,
  300. 'post_date' => $wp_query->post->post_date,
  301. 'post_date_gmt' => $wp_query->post->post_date_gmt,
  302. 'post_modified' => $wp_query->post->post_modified,
  303. 'post_modified_gmt' => $wp_query->post->post_modified_gmt,
  304. 'post_content' => $wp_query->post->post_content,
  305. 'post_title' => $wp_query->post->post_title,
  306. 'post_excerpt' => $wp_query->post->post_excerpt,
  307. 'post_content_filtered' => $wp_query->post->post_content_filtered,
  308. 'post_mime_type' => $wp_query->post->post_mime_type,
  309. 'post_password' => $wp_query->post->post_password,
  310. 'post_name' => $wp_query->post->post_name,
  311. 'guid' => $wp_query->post->guid,
  312. 'menu_order' => $wp_query->post->menu_order,
  313. 'pinged' => $wp_query->post->pinged,
  314. 'to_ping' => $wp_query->post->to_ping,
  315. 'ping_status' => $wp_query->post->ping_status,
  316. 'comment_status' => $wp_query->post->comment_status,
  317. 'comment_count' => $wp_query->post->comment_count,
  318. 'is_404' => false,
  319. 'is_page' => false,
  320. 'is_single' => false,
  321. 'is_archive' => false,
  322. 'is_tax' => false,
  323. );
  324. }
  325. $dummy = bbp_parse_args( $args, $defaults, 'theme_compat_reset_post' );
  326. // Clear out the post related globals
  327. unset( $wp_query->posts );
  328. unset( $wp_query->post );
  329. unset( $post );
  330. // Setup the dummy post object
  331. $wp_query->post = new stdClass;
  332. $wp_query->post->ID = $dummy['ID'];
  333. $wp_query->post->post_status = $dummy['post_status'];
  334. $wp_query->post->post_author = $dummy['post_author'];
  335. $wp_query->post->post_parent = $dummy['post_parent'];
  336. $wp_query->post->post_type = $dummy['post_type'];
  337. $wp_query->post->post_date = $dummy['post_date'];
  338. $wp_query->post->post_date_gmt = $dummy['post_date_gmt'];
  339. $wp_query->post->post_modified = $dummy['post_modified'];
  340. $wp_query->post->post_modified_gmt = $dummy['post_modified_gmt'];
  341. $wp_query->post->post_content = $dummy['post_content'];
  342. $wp_query->post->post_title = $dummy['post_title'];
  343. $wp_query->post->post_excerpt = $dummy['post_excerpt'];
  344. $wp_query->post->post_content_filtered = $dummy['post_content_filtered'];
  345. $wp_query->post->post_mime_type = $dummy['post_mime_type'];
  346. $wp_query->post->post_password = $dummy['post_password'];
  347. $wp_query->post->post_name = $dummy['post_name'];
  348. $wp_query->post->guid = $dummy['guid'];
  349. $wp_query->post->menu_order = $dummy['menu_order'];
  350. $wp_query->post->pinged = $dummy['pinged'];
  351. $wp_query->post->to_ping = $dummy['to_ping'];
  352. $wp_query->post->ping_status = $dummy['ping_status'];
  353. $wp_query->post->comment_status = $dummy['comment_status'];
  354. $wp_query->post->comment_count = $dummy['comment_count'];
  355. // Set the $post global
  356. $post = $wp_query->post;
  357. // Setup the dummy post loop
  358. $wp_query->posts[0] = $wp_query->post;
  359. // Prevent comments form from appearing
  360. $wp_query->post_count = 1;
  361. $wp_query->is_404 = $dummy['is_404'];
  362. $wp_query->is_page = $dummy['is_page'];
  363. $wp_query->is_single = $dummy['is_single'];
  364. $wp_query->is_archive = $dummy['is_archive'];
  365. $wp_query->is_tax = $dummy['is_tax'];
  366. /**
  367. * Force the header back to 200 status if not a deliberate 404
  368. *
  369. * @see http://bbpress.trac.wordpress.org/ticket/1973
  370. */
  371. if ( ! $wp_query->is_404() )
  372. status_header( 200 );
  373. // If we are resetting a post, we are in theme compat
  374. bbp_set_theme_compat_active();
  375. }
  376. /**
  377. * Reset main query vars and filter 'the_content' to output a bbPress
  378. * template part as needed.
  379. *
  380. * @since bbPress (r3032)
  381. * @param string $template
  382. * @uses bbp_is_single_user() To check if page is single user
  383. * @uses bbp_get_single_user_template() To get user template
  384. * @uses bbp_is_single_user_edit() To check if page is single user edit
  385. * @uses bbp_get_single_user_edit_template() To get user edit template
  386. * @uses bbp_is_single_view() To check if page is single view
  387. * @uses bbp_get_single_view_template() To get view template
  388. * @uses bbp_is_search() To check if page is search
  389. * @uses bbp_get_search_template() To get search template
  390. * @uses bbp_is_forum_edit() To check if page is forum edit
  391. * @uses bbp_get_forum_edit_template() To get forum edit template
  392. * @uses bbp_is_topic_merge() To check if page is topic merge
  393. * @uses bbp_get_topic_merge_template() To get topic merge template
  394. * @uses bbp_is_topic_split() To check if page is topic split
  395. * @uses bbp_get_topic_split_template() To get topic split template
  396. * @uses bbp_is_topic_edit() To check if page is topic edit
  397. * @uses bbp_get_topic_edit_template() To get topic edit template
  398. * @uses bbp_is_reply_move() To check if page is reply move
  399. * @uses bbp_get_reply_move_template() To get reply move template
  400. * @uses bbp_is_reply_edit() To check if page is reply edit
  401. * @uses bbp_get_reply_edit_template() To get reply edit template
  402. * @uses bbp_set_theme_compat_template() To set the global theme compat template
  403. */
  404. function bbp_template_include_theme_compat( $template = '' ) {
  405. /**
  406. * If BuddyPress is activated at a network level, the action order is
  407. * reversed, which causes the template integration to fail. If we're looking
  408. * at a BuddyPress page here, bail to prevent the extra processing.
  409. *
  410. * This is a bit more brute-force than is probably necessary, but gets the
  411. * job done while we work towards something more elegant.
  412. */
  413. if ( function_exists( 'is_buddypress' ) && is_buddypress() )
  414. return $template;
  415. /** Users *************************************************************/
  416. if ( bbp_is_single_user_edit() || bbp_is_single_user() ) {
  417. // Reset post
  418. bbp_theme_compat_reset_post( array(
  419. 'ID' => 0,
  420. 'post_author' => 0,
  421. 'post_date' => 0,
  422. 'post_content' => '',
  423. 'post_type' => '',
  424. 'post_title' => esc_attr( bbp_get_displayed_user_field( 'display_name' ) ),
  425. 'post_status' => bbp_get_public_status_id(),
  426. 'is_archive' => false,
  427. 'comment_status' => 'closed'
  428. ) );
  429. /** Forums ************************************************************/
  430. // Forum archive
  431. } elseif ( bbp_is_forum_archive() ) {
  432. // Reset post
  433. bbp_theme_compat_reset_post( array(
  434. 'ID' => 0,
  435. 'post_title' => bbp_get_forum_archive_title(),
  436. 'post_author' => 0,
  437. 'post_date' => 0,
  438. 'post_content' => '',
  439. 'post_type' => bbp_get_forum_post_type(),
  440. 'post_status' => bbp_get_public_status_id(),
  441. 'is_archive' => true,
  442. 'comment_status' => 'closed'
  443. ) );
  444. // Single Forum
  445. } elseif ( bbp_is_forum_edit() || bbp_is_single_forum() ) {
  446. // Reset post
  447. bbp_theme_compat_reset_post( array(
  448. 'ID' => bbp_get_forum_id(),
  449. 'post_title' => bbp_get_forum_title(),
  450. 'post_author' => bbp_get_forum_author_id(),
  451. 'post_date' => 0,
  452. 'post_content' => get_post_field( 'post_content', bbp_get_forum_id() ),
  453. 'post_type' => bbp_get_forum_post_type(),
  454. 'post_status' => bbp_get_forum_visibility(),
  455. 'is_single' => true,
  456. 'comment_status' => 'closed'
  457. ) );
  458. /** Topics ************************************************************/
  459. // Topic archive
  460. } elseif ( bbp_is_topic_archive() ) {
  461. // Reset post
  462. bbp_theme_compat_reset_post( array(
  463. 'ID' => 0,
  464. 'post_title' => bbp_get_topic_archive_title(),
  465. 'post_author' => 0,
  466. 'post_date' => 0,
  467. 'post_content' => '',
  468. 'post_type' => bbp_get_topic_post_type(),
  469. 'post_status' => bbp_get_public_status_id(),
  470. 'is_archive' => true,
  471. 'comment_status' => 'closed'
  472. ) );
  473. // Single Topic
  474. } elseif ( bbp_is_topic_edit() || bbp_is_single_topic() ) {
  475. // Reset post
  476. bbp_theme_compat_reset_post( array(
  477. 'ID' => bbp_get_topic_id(),
  478. 'post_title' => bbp_get_topic_title(),
  479. 'post_author' => bbp_get_topic_author_id(),
  480. 'post_date' => 0,
  481. 'post_content' => get_post_field( 'post_content', bbp_get_topic_id() ),
  482. 'post_type' => bbp_get_topic_post_type(),
  483. 'post_status' => bbp_get_topic_status(),
  484. 'is_single' => true,
  485. 'comment_status' => 'closed'
  486. ) );
  487. /** Replies ***********************************************************/
  488. // Reply archive
  489. } elseif ( is_post_type_archive( bbp_get_reply_post_type() ) ) {
  490. // Reset post
  491. bbp_theme_compat_reset_post( array(
  492. 'ID' => 0,
  493. 'post_title' => __( 'Replies', 'bbpress' ),
  494. 'post_author' => 0,
  495. 'post_date' => 0,
  496. 'post_content' => '',
  497. 'post_type' => bbp_get_reply_post_type(),
  498. 'post_status' => bbp_get_public_status_id(),
  499. 'comment_status' => 'closed'
  500. ) );
  501. // Single Reply
  502. } elseif ( bbp_is_reply_edit() || bbp_is_single_reply() ) {
  503. // Reset post
  504. bbp_theme_compat_reset_post( array(
  505. 'ID' => bbp_get_reply_id(),
  506. 'post_title' => bbp_get_reply_title(),
  507. 'post_author' => bbp_get_reply_author_id(),
  508. 'post_date' => 0,
  509. 'post_content' => get_post_field( 'post_content', bbp_get_reply_id() ),
  510. 'post_type' => bbp_get_reply_post_type(),
  511. 'post_status' => bbp_get_reply_status(),
  512. 'comment_status' => 'closed'
  513. ) );
  514. /** Views *************************************************************/
  515. } elseif ( bbp_is_single_view() ) {
  516. // Reset post
  517. bbp_theme_compat_reset_post( array(
  518. 'ID' => 0,
  519. 'post_title' => bbp_get_view_title(),
  520. 'post_author' => 0,
  521. 'post_date' => 0,
  522. 'post_content' => '',
  523. 'post_type' => '',
  524. 'post_status' => bbp_get_public_status_id(),
  525. 'comment_status' => 'closed'
  526. ) );
  527. /** Search ************************************************************/
  528. } elseif ( bbp_is_search() ) {
  529. // Reset post
  530. bbp_theme_compat_reset_post( array(
  531. 'ID' => 0,
  532. 'post_title' => bbp_get_search_title(),
  533. 'post_author' => 0,
  534. 'post_date' => 0,
  535. 'post_content' => '',
  536. 'post_type' => '',
  537. 'post_status' => bbp_get_public_status_id(),
  538. 'comment_status' => 'closed'
  539. ) );
  540. /** Topic Tags ********************************************************/
  541. // Topic Tag Edit
  542. } elseif ( bbp_is_topic_tag_edit() || bbp_is_topic_tag() ) {
  543. // Stash the current term in a new var
  544. set_query_var( 'bbp_topic_tag', get_query_var( 'term' ) );
  545. // Reset the post with our new title
  546. bbp_theme_compat_reset_post( array(
  547. 'ID' => 0,
  548. 'post_author' => 0,
  549. 'post_date' => 0,
  550. 'post_content' => '',
  551. 'post_type' => '',
  552. 'post_title' => sprintf( __( 'Topic Tag: %s', 'bbpress' ), '<span>' . bbp_get_topic_tag_name() . '</span>' ),
  553. 'post_status' => bbp_get_public_status_id(),
  554. 'comment_status' => 'closed'
  555. ) );
  556. }
  557. /**
  558. * Bail if the template already matches a bbPress template. This includes
  559. * archive-* and single-* WordPress post_type matches (allowing
  560. * themes to use the expected format) as well as all bbPress-specific
  561. * template files for users, topics, forums, etc...
  562. *
  563. * We do this after the above checks to prevent incorrect 404 body classes
  564. * and header statuses.
  565. *
  566. * @see http://bbpress.trac.wordpress.org/ticket/1478/
  567. */
  568. if ( !empty( bbpress()->theme_compat->bbpress_template ) )
  569. return $template;
  570. /**
  571. * If we are relying on bbPress's built in theme compatibility to load
  572. * the proper content, we need to intercept the_content, replace the
  573. * output, and display ours instead.
  574. *
  575. * To do this, we first remove all filters from 'the_content' and hook
  576. * our own function into it, which runs a series of checks to determine
  577. * the context, and then uses the built in shortcodes to output the
  578. * correct results from inside an output buffer.
  579. *
  580. * Uses bbp_get_theme_compat_templates() to provide fall-backs that
  581. * should be coded without superfluous mark-up and logic (prev/next
  582. * navigation, comments, date/time, etc...)
  583. *
  584. * Hook into the 'bbp_get_bbpress_template' to override the array of
  585. * possible templates, or 'bbp_bbpress_template' to override the result.
  586. */
  587. if ( bbp_is_theme_compat_active() ) {
  588. // Remove all filters from the_content
  589. bbp_remove_all_filters( 'the_content' );
  590. // Add a filter on the_content late, which we will later remove
  591. add_filter( 'the_content', 'bbp_replace_the_content' );
  592. // Find the appropriate template file
  593. $template = bbp_get_theme_compat_templates();
  594. }
  595. return apply_filters( 'bbp_template_include_theme_compat', $template );
  596. }
  597. /**
  598. * Replaces the_content() if the post_type being displayed is one that would
  599. * normally be handled by bbPress, but proper single page templates do not
  600. * exist in the currently active theme.
  601. *
  602. * Note that we do *not* currently use is_main_query() here. This is because so
  603. * many existing themes either use query_posts() or fail to use wp_reset_query()
  604. * when running queries before the main loop, causing theme compat to fail.
  605. *
  606. * @since bbPress (r3034)
  607. * @param string $content
  608. * @return type
  609. */
  610. function bbp_replace_the_content( $content = '' ) {
  611. // Bail if not inside the query loop
  612. if ( ! in_the_loop() )
  613. return $content;
  614. $bbp = bbpress();
  615. // Define local variable(s)
  616. $new_content = '';
  617. // Bail if shortcodes are unset somehow
  618. if ( !is_a( $bbp->shortcodes, 'BBP_Shortcodes' ) )
  619. return $content;
  620. // Use shortcode API to display forums/topics/replies because they are
  621. // already output buffered and ready to fit inside the_content
  622. /** Users *************************************************************/
  623. // Profile View
  624. if ( bbp_is_single_user_edit() || bbp_is_single_user() ) {
  625. ob_start();
  626. bbp_get_template_part( 'content', 'single-user' );
  627. $new_content = ob_get_contents();
  628. ob_end_clean();
  629. /** Forums ************************************************************/
  630. // Forum archive
  631. } elseif ( bbp_is_forum_archive() ) {
  632. // Page exists where this archive should be
  633. $page = bbp_get_page_by_path( bbp_get_root_slug() );
  634. if ( !empty( $page ) ) {
  635. // Restore previously unset filters
  636. bbp_restore_all_filters( 'the_content' );
  637. // Remove 'bbp_replace_the_content' filter to prevent infinite loops
  638. remove_filter( 'the_content', 'bbp_replace_the_content' );
  639. // Start output buffer
  640. ob_start();
  641. // Grab the content of this page
  642. $new_content = apply_filters( 'the_content', $page->post_content );
  643. // Clean up the buffer
  644. ob_end_clean();
  645. // Add 'bbp_replace_the_content' filter back (@see $this::start())
  646. add_filter( 'the_content', 'bbp_replace_the_content' );
  647. // No page so show the archive
  648. } else {
  649. $new_content = $bbp->shortcodes->display_forum_index();
  650. }
  651. // Forum Edit
  652. } elseif ( bbp_is_forum_edit() ) {
  653. $new_content = $bbp->shortcodes->display_forum_form();
  654. // Single Forum
  655. } elseif ( bbp_is_single_forum() ) {
  656. $new_content = $bbp->shortcodes->display_forum( array( 'id' => get_the_ID() ) );
  657. /** Topics ************************************************************/
  658. // Topic archive
  659. } elseif ( bbp_is_topic_archive() ) {
  660. // Page exists where this archive should be
  661. $page = bbp_get_page_by_path( bbp_get_topic_archive_slug() );
  662. if ( !empty( $page ) ) {
  663. // Restore previously unset filters
  664. bbp_restore_all_filters( 'the_content' );
  665. // Remove 'bbp_replace_the_content' filter to prevent infinite loops
  666. remove_filter( 'the_content', 'bbp_replace_the_content' );
  667. // Start output buffer
  668. ob_start();
  669. // Grab the content of this page
  670. $new_content = apply_filters( 'the_content', $page->post_content );
  671. // Clean up the buffer
  672. ob_end_clean();
  673. // Add 'bbp_replace_the_content' filter back (@see $this::start())
  674. add_filter( 'the_content', 'bbp_replace_the_content' );
  675. // No page so show the archive
  676. } else {
  677. $new_content = $bbp->shortcodes->display_topic_index();
  678. }
  679. // Topic Edit
  680. } elseif ( bbp_is_topic_edit() ) {
  681. // Split
  682. if ( bbp_is_topic_split() ) {
  683. ob_start();
  684. bbp_get_template_part( 'form', 'topic-split' );
  685. $new_content = ob_get_contents();
  686. ob_end_clean();
  687. // Merge
  688. } elseif ( bbp_is_topic_merge() ) {
  689. ob_start();
  690. bbp_get_template_part( 'form', 'topic-merge' );
  691. $new_content = ob_get_contents();
  692. ob_end_clean();
  693. // Edit
  694. } else {
  695. $new_content = $bbp->shortcodes->display_topic_form();
  696. }
  697. // Single Topic
  698. } elseif ( bbp_is_single_topic() ) {
  699. $new_content = $bbp->shortcodes->display_topic( array( 'id' => get_the_ID() ) );
  700. /** Replies ***********************************************************/
  701. // Reply archive
  702. } elseif ( is_post_type_archive( bbp_get_reply_post_type() ) ) {
  703. //$new_content = $bbp->shortcodes->display_reply_index();
  704. // Reply Edit
  705. } elseif ( bbp_is_reply_edit() ) {
  706. // Move
  707. if ( bbp_is_reply_move() ) {
  708. ob_start();
  709. bbp_get_template_part( 'form', 'reply-move' );
  710. $new_content = ob_get_contents();
  711. ob_end_clean();
  712. // Edit
  713. } else {
  714. $new_content = $bbp->shortcodes->display_reply_form();
  715. }
  716. // Single Reply
  717. } elseif ( bbp_is_single_reply() ) {
  718. $new_content = $bbp->shortcodes->display_reply( array( 'id' => get_the_ID() ) );
  719. /** Views *************************************************************/
  720. } elseif ( bbp_is_single_view() ) {
  721. $new_content = $bbp->shortcodes->display_view( array( 'id' => get_query_var( 'bbp_view' ) ) );
  722. /** Search ************************************************************/
  723. } elseif ( bbp_is_search() ) {
  724. $new_content = $bbp->shortcodes->display_search( array( 'search' => get_query_var( 'bbp_search' ) ) );
  725. /** Topic Tags ********************************************************/
  726. // Show topics of tag
  727. } elseif ( bbp_is_topic_tag() ) {
  728. $new_content = $bbp->shortcodes->display_topics_of_tag( array( 'id' => bbp_get_topic_tag_id() ) );
  729. // Edit topic tag
  730. } elseif ( bbp_is_topic_tag_edit() ) {
  731. $new_content = $bbp->shortcodes->display_topic_tag_form();
  732. }
  733. // Juggle the content around and try to prevent unsightly comments
  734. if ( !empty( $new_content ) && ( $new_content != $content ) ) {
  735. // Set the content to be the new content
  736. $content = apply_filters( 'bbp_replace_the_content', $new_content, $content );
  737. // Clean up after ourselves
  738. unset( $new_content );
  739. // Reset the $post global
  740. wp_reset_postdata();
  741. }
  742. // Return possibly hi-jacked content
  743. return $content;
  744. }
  745. /** Helpers *******************************************************************/
  746. /**
  747. * Remove the canonical redirect to allow pretty pagination
  748. *
  749. * @since bbPress (r2628)
  750. * @param string $redirect_url Redirect url
  751. * @uses WP_Rewrite::using_permalinks() To check if the blog is using permalinks
  752. * @uses bbp_get_paged() To get the current page number
  753. * @uses bbp_is_single_topic() To check if it's a topic page
  754. * @uses bbp_is_single_forum() To check if it's a forum page
  755. * @return bool|string False if it's a topic/forum and their first page,
  756. * otherwise the redirect url
  757. */
  758. function bbp_redirect_canonical( $redirect_url ) {
  759. global $wp_rewrite;
  760. // Canonical is for the beautiful
  761. if ( $wp_rewrite->using_permalinks() ) {
  762. // If viewing beyond page 1 of several
  763. if ( 1 < bbp_get_paged() ) {
  764. // Only on single topics...
  765. if ( bbp_is_single_topic() ) {
  766. $redirect_url = false;
  767. // ...and single forums...
  768. } elseif ( bbp_is_single_forum() ) {
  769. $redirect_url = false;
  770. // ...and single replies...
  771. } elseif ( bbp_is_single_reply() ) {
  772. $redirect_url = false;
  773. // ...and any single anything else...
  774. //
  775. // @todo - Find a more accurate way to disable paged canonicals for
  776. // paged shortcode usage within other posts.
  777. } elseif ( is_page() || is_singular() ) {
  778. $redirect_url = false;
  779. }
  780. // If editing a topic
  781. } elseif ( bbp_is_topic_edit() ) {
  782. $redirect_url = false;
  783. // If editing a reply
  784. } elseif ( bbp_is_reply_edit() ) {
  785. $redirect_url = false;
  786. }
  787. }
  788. return $redirect_url;
  789. }
  790. /** Filters *******************************************************************/
  791. /**
  792. * Removes all filters from a WordPress filter, and stashes them in the $bbp
  793. * global in the event they need to be restored later.
  794. *
  795. * @since bbPress (r3251)
  796. * @global WP_filter $wp_filter
  797. * @global array $merged_filters
  798. * @param string $tag
  799. * @param int $priority
  800. * @return bool
  801. */
  802. function bbp_remove_all_filters( $tag, $priority = false ) {
  803. global $wp_filter, $merged_filters;
  804. $bbp = bbpress();
  805. // Filters exist
  806. if ( isset( $wp_filter[$tag] ) ) {
  807. // Filters exist in this priority
  808. if ( !empty( $priority ) && isset( $wp_filter[$tag][$priority] ) ) {
  809. // Store filters in a backup
  810. $bbp->filters->wp_filter[$tag][$priority] = $wp_filter[$tag][$priority];
  811. // Unset the filters
  812. unset( $wp_filter[$tag][$priority] );
  813. // Priority is empty
  814. } else {
  815. // Store filters in a backup
  816. $bbp->filters->wp_filter[$tag] = $wp_filter[$tag];
  817. // Unset the filters
  818. unset( $wp_filter[$tag] );
  819. }
  820. }
  821. // Check merged filters
  822. if ( isset( $merged_filters[$tag] ) ) {
  823. // Store filters in a backup
  824. $bbp->filters->merged_filters[$tag] = $merged_filters[$tag];
  825. // Unset the filters
  826. unset( $merged_filters[$tag] );
  827. }
  828. return true;
  829. }
  830. /**
  831. * Restores filters from the $bbp global that were removed using
  832. * bbp_remove_all_filters()
  833. *
  834. * @since bbPress (r3251)
  835. * @global WP_filter $wp_filter
  836. * @global array $merged_filters
  837. * @param string $tag
  838. * @param int $priority
  839. * @return bool
  840. */
  841. function bbp_restore_all_filters( $tag, $priority = false ) {
  842. global $wp_filter, $merged_filters;
  843. $bbp = bbpress();
  844. // Filters exist
  845. if ( isset( $bbp->filters->wp_filter[$tag] ) ) {
  846. // Filters exist in this priority
  847. if ( !empty( $priority ) && isset( $bbp->filters->wp_filter[$tag][$priority] ) ) {
  848. // Store filters in a backup
  849. $wp_filter[$tag][$priority] = $bbp->filters->wp_filter[$tag][$priority];
  850. // Unset the filters
  851. unset( $bbp->filters->wp_filter[$tag][$priority] );
  852. // Priority is empty
  853. } else {
  854. // Store filters in a backup
  855. $wp_filter[$tag] = $bbp->filters->wp_filter[$tag];
  856. // Unset the filters
  857. unset( $bbp->filters->wp_filter[$tag] );
  858. }
  859. }
  860. // Check merged filters
  861. if ( isset( $bbp->filters->merged_filters[$tag] ) ) {
  862. // Store filters in a backup
  863. $merged_filters[$tag] = $bbp->filters->merged_filters[$tag];
  864. // Unset the filters
  865. unset( $bbp->filters->merged_filters[$tag] );
  866. }
  867. return true;
  868. }
  869. /**
  870. * Force comments_status to 'closed' for bbPress post types
  871. *
  872. * @since bbPress (r3589)
  873. * @param bool $open True if open, false if closed
  874. * @param int $post_id ID of the post to check
  875. * @return bool True if open, false if closed
  876. */
  877. function bbp_force_comment_status( $open, $post_id = 0 ) {
  878. // Get the post type of the post ID
  879. $post_type = get_post_type( $post_id );
  880. // Default return value is what is passed in $open
  881. $retval = $open;
  882. // Only force for bbPress post types
  883. switch ( $post_type ) {
  884. case bbp_get_forum_post_type() :
  885. case bbp_get_topic_post_type() :
  886. case bbp_get_reply_post_type() :
  887. $retval = false;
  888. break;
  889. }
  890. // Allow override of the override
  891. return apply_filters( 'bbp_force_comment_status', $retval, $open, $post_id, $post_type );
  892. }