/includes/forums/functions.php

  1. <?php 
  2.  
  3. /** 
  4. * bbPress Forum Functions 
  5. * 
  6. * @package bbPress 
  7. * @subpackage Functions 
  8. */ 
  9.  
  10. // Exit if accessed directly 
  11. if ( !defined( 'ABSPATH' ) ) exit; 
  12.  
  13. /** Insert ********************************************************************/ 
  14.  
  15. /** 
  16. * A wrapper for wp_insert_post() that also includes the necessary meta values 
  17. * for the forum to function properly. 
  18. * 
  19. * @since bbPress (r3349) 
  20. * 
  21. * @uses bbp_parse_args() 
  22. * @uses bbp_get_forum_post_type() 
  23. * @uses wp_insert_post() 
  24. * @uses update_post_meta() 
  25. * 
  26. * @param array $forum_data Forum post data 
  27. * @param arrap $forum_meta Forum meta data 
  28. */ 
  29. function bbp_insert_forum( $forum_data = array(), $forum_meta = array() ) { 
  30.  
  31. // Forum 
  32. $forum_data = bbp_parse_args( $forum_data, array( 
  33. 'post_parent' => 0, // forum ID 
  34. 'post_status' => bbp_get_public_status_id(),  
  35. 'post_type' => bbp_get_forum_post_type(),  
  36. 'post_author' => bbp_get_current_user_id(),  
  37. 'post_password' => '',  
  38. 'post_content' => '',  
  39. 'post_title' => '',  
  40. 'menu_order' => 0,  
  41. 'comment_status' => 'closed' 
  42. ), 'insert_forum' ); 
  43.  
  44. // Insert forum 
  45. $forum_id = wp_insert_post( $forum_data ); 
  46.  
  47. // Bail if no forum was added 
  48. if ( empty( $forum_id ) ) { 
  49. return false; 
  50.  
  51. // Forum meta 
  52. $forum_meta = bbp_parse_args( $forum_meta, array( 
  53. 'reply_count' => 0,  
  54. 'topic_count' => 0,  
  55. 'topic_count_hidden' => 0,  
  56. 'total_reply_count' => 0,  
  57. 'total_topic_count' => 0,  
  58. 'last_topic_id' => 0,  
  59. 'last_reply_id' => 0,  
  60. 'last_active_id' => 0,  
  61. 'last_active_time' => 0,  
  62. 'forum_subforum_count' => 0,  
  63. ), 'insert_forum_meta' ); 
  64.  
  65. // Insert forum meta 
  66. foreach ( $forum_meta as $meta_key => $meta_value ) { 
  67. update_post_meta( $forum_id, '_bbp_' . $meta_key, $meta_value ); 
  68.  
  69. // Return new forum ID 
  70. return $forum_id; 
  71.  
  72. /** Post Form Handlers ********************************************************/ 
  73.  
  74. /** 
  75. * Handles the front end forum submission 
  76. * 
  77. * @param string $action The requested action to compare this function to 
  78. * @uses bbp_add_error() To add an error message 
  79. * @uses bbp_verify_nonce_request() To verify the nonce and check the request 
  80. * @uses bbp_is_anonymous() To check if an anonymous post is being made 
  81. * @uses current_user_can() To check if the current user can publish forum 
  82. * @uses bbp_get_current_user_id() To get the current user id 
  83. * @uses bbp_filter_anonymous_post_data() To filter anonymous data 
  84. * @uses bbp_set_current_anonymous_user_data() To set the anonymous user cookies 
  85. * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error} 
  86. * @uses esc_attr() For sanitization 
  87. * @uses bbp_is_forum_category() To check if the forum is a category 
  88. * @uses bbp_is_forum_closed() To check if the forum is closed 
  89. * @uses bbp_is_forum_private() To check if the forum is private 
  90. * @uses bbp_check_for_flood() To check for flooding 
  91. * @uses bbp_check_for_duplicate() To check for duplicates 
  92. * @uses bbp_get_forum_post_type() To get the forum post type 
  93. * @uses remove_filter() To remove kses filters if needed 
  94. * @uses apply_filters() Calls 'bbp_new_forum_pre_title' with the content 
  95. * @uses apply_filters() Calls 'bbp_new_forum_pre_content' with the content 
  96. * @uses bbPress::errors::get_error_codes() To get the {@link WP_Error} errors 
  97. * @uses wp_insert_post() To insert the forum 
  98. * @uses do_action() Calls 'bbp_new_forum' with the forum id, forum id,  
  99. * anonymous data and reply author 
  100. * @uses bbp_stick_forum() To stick or super stick the forum 
  101. * @uses bbp_unstick_forum() To unstick the forum 
  102. * @uses bbp_get_forum_permalink() To get the forum permalink 
  103. * @uses wp_safe_redirect() To redirect to the forum link 
  104. * @uses bbPress::errors::get_error_messages() To get the {@link WP_Error} error 
  105. * messages 
  106. */ 
  107. function bbp_new_forum_handler( $action = '' ) { 
  108.  
  109. // Bail if action is not bbp-new-forum 
  110. if ( 'bbp-new-forum' !== $action ) 
  111. return; 
  112.  
  113. // Nonce check 
  114. if ( ! bbp_verify_nonce_request( 'bbp-new-forum' ) ) { 
  115. bbp_add_error( 'bbp_new_forum_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) ); 
  116. return; 
  117.  
  118. // Define local variable(s) 
  119. $view_all = $anonymous_data = false; 
  120. $forum_parent_id = $forum_author = 0; 
  121. $forum_title = $forum_content = ''; 
  122.  
  123. /** Forum Author **********************************************************/ 
  124.  
  125. // User cannot create forums 
  126. if ( !current_user_can( 'publish_forums' ) ) { 
  127. bbp_add_error( 'bbp_forum_permissions', __( '<strong>ERROR</strong>: You do not have permission to create new forums.', 'bbpress' ) ); 
  128. return; 
  129.  
  130. // Forum author is current user 
  131. $forum_author = bbp_get_current_user_id(); 
  132.  
  133. // Remove kses filters from title and content for capable users and if the nonce is verified 
  134. if ( current_user_can( 'unfiltered_html' ) && !empty( $_POST['_bbp_unfiltered_html_forum'] ) && wp_create_nonce( 'bbp-unfiltered-html-forum_new' ) === $_POST['_bbp_unfiltered_html_forum'] ) { 
  135. remove_filter( 'bbp_new_forum_pre_title', 'wp_filter_kses' ); 
  136. remove_filter( 'bbp_new_forum_pre_content', 'bbp_encode_bad', 10 ); 
  137. remove_filter( 'bbp_new_forum_pre_content', 'bbp_filter_kses', 30 ); 
  138.  
  139. /** Forum Title ***********************************************************/ 
  140.  
  141. if ( !empty( $_POST['bbp_forum_title'] ) ) 
  142. $forum_title = esc_attr( strip_tags( $_POST['bbp_forum_title'] ) ); 
  143.  
  144. // Filter and sanitize 
  145. $forum_title = apply_filters( 'bbp_new_forum_pre_title', $forum_title ); 
  146.  
  147. // No forum title 
  148. if ( empty( $forum_title ) ) 
  149. bbp_add_error( 'bbp_forum_title', __( '<strong>ERROR</strong>: Your forum needs a title.', 'bbpress' ) ); 
  150.  
  151. /** Forum Content *********************************************************/ 
  152.  
  153. if ( !empty( $_POST['bbp_forum_content'] ) ) 
  154. $forum_content = $_POST['bbp_forum_content']; 
  155.  
  156. // Filter and sanitize 
  157. $forum_content = apply_filters( 'bbp_new_forum_pre_content', $forum_content ); 
  158.  
  159. // No forum content 
  160. if ( empty( $forum_content ) ) 
  161. bbp_add_error( 'bbp_forum_content', __( '<strong>ERROR</strong>: Your forum description cannot be empty.', 'bbpress' ) ); 
  162.  
  163. /** Forum Parent **********************************************************/ 
  164.  
  165. // Forum parent was passed (the norm) 
  166. if ( !empty( $_POST['bbp_forum_parent_id'] ) ) { 
  167. $forum_parent_id = bbp_get_forum_id( $_POST['bbp_forum_parent_id'] ); 
  168.  
  169. // Filter and sanitize 
  170. $forum_parent_id = apply_filters( 'bbp_new_forum_pre_parent_id', $forum_parent_id ); 
  171.  
  172. // No forum parent was passed (should never happen) 
  173. if ( empty( $forum_parent_id ) ) { 
  174. bbp_add_error( 'bbp_new_forum_missing_parent', __( '<strong>ERROR</strong>: Your forum must have a parent.', 'bbpress' ) ); 
  175.  
  176. // Forum exists 
  177. } elseif ( !empty( $forum_parent_id ) ) { 
  178.  
  179. // Forum is a category 
  180. if ( bbp_is_forum_category( $forum_parent_id ) ) { 
  181. bbp_add_error( 'bbp_new_forum_forum_category', __( '<strong>ERROR</strong>: This forum is a category. No forums can be created in this forum.', 'bbpress' ) ); 
  182.  
  183. // Forum is closed and user cannot access 
  184. if ( bbp_is_forum_closed( $forum_parent_id ) && !current_user_can( 'edit_forum', $forum_parent_id ) ) { 
  185. bbp_add_error( 'bbp_new_forum_forum_closed', __( '<strong>ERROR</strong>: This forum has been closed to new forums.', 'bbpress' ) ); 
  186.  
  187. // Forum is private and user cannot access 
  188. if ( bbp_is_forum_private( $forum_parent_id ) && !current_user_can( 'read_private_forums' ) ) { 
  189. bbp_add_error( 'bbp_new_forum_forum_private', __( '<strong>ERROR</strong>: This forum is private and you do not have the capability to read or create new forums in it.', 'bbpress' ) ); 
  190.  
  191. // Forum is hidden and user cannot access 
  192. if ( bbp_is_forum_hidden( $forum_parent_id ) && !current_user_can( 'read_hidden_forums' ) ) { 
  193. bbp_add_error( 'bbp_new_forum_forum_hidden', __( '<strong>ERROR</strong>: This forum is hidden and you do not have the capability to read or create new forums in it.', 'bbpress' ) ); 
  194.  
  195. /** Forum Flooding ********************************************************/ 
  196.  
  197. if ( !bbp_check_for_flood( $anonymous_data, $forum_author ) ) 
  198. bbp_add_error( 'bbp_forum_flood', __( '<strong>ERROR</strong>: Slow down; you move too fast.', 'bbpress' ) ); 
  199.  
  200. /** Forum Duplicate *******************************************************/ 
  201.  
  202. if ( !bbp_check_for_duplicate( array( 'post_type' => bbp_get_forum_post_type(), 'post_author' => $forum_author, 'post_content' => $forum_content, 'anonymous_data' => $anonymous_data ) ) ) 
  203. bbp_add_error( 'bbp_forum_duplicate', __( '<strong>ERROR</strong>: This forum already exists.', 'bbpress' ) ); 
  204.  
  205. /** Forum Blacklist *******************************************************/ 
  206.  
  207. if ( !bbp_check_for_blacklist( $anonymous_data, $forum_author, $forum_title, $forum_content ) ) 
  208. bbp_add_error( 'bbp_forum_blacklist', __( '<strong>ERROR</strong>: Your forum cannot be created at this time.', 'bbpress' ) ); 
  209.  
  210. /** Forum Moderation ******************************************************/ 
  211.  
  212. $post_status = bbp_get_public_status_id(); 
  213. if ( !bbp_check_for_moderation( $anonymous_data, $forum_author, $forum_title, $forum_content ) ) 
  214. $post_status = bbp_get_pending_status_id(); 
  215.  
  216. /** Additional Actions (Before Save) **************************************/ 
  217.  
  218. do_action( 'bbp_new_forum_pre_extras', $forum_parent_id ); 
  219.  
  220. // Bail if errors 
  221. if ( bbp_has_errors() ) 
  222. return; 
  223.  
  224. /** No Errors *************************************************************/ 
  225.  
  226. // Add the content of the form to $forum_data as an array 
  227. // Just in time manipulation of forum data before being created 
  228. $forum_data = apply_filters( 'bbp_new_forum_pre_insert', array( 
  229. 'post_author' => $forum_author,  
  230. 'post_title' => $forum_title,  
  231. 'post_content' => $forum_content,  
  232. 'post_parent' => $forum_parent_id,  
  233. 'post_status' => $post_status,  
  234. 'post_type' => bbp_get_forum_post_type(),  
  235. 'comment_status' => 'closed' 
  236. ) ); 
  237.  
  238. // Insert forum 
  239. $forum_id = wp_insert_post( $forum_data ); 
  240.  
  241. /** No Errors *************************************************************/ 
  242.  
  243. if ( !empty( $forum_id ) && !is_wp_error( $forum_id ) ) { 
  244.  
  245. /** Trash Check *******************************************************/ 
  246.  
  247. // If the forum is trash, or the forum_status is switched to 
  248. // trash, trash it properly 
  249. if ( ( get_post_field( 'post_status', $forum_id ) === bbp_get_trash_status_id() ) || ( $forum_data['post_status'] === bbp_get_trash_status_id() ) ) { 
  250.  
  251. // Trash the reply 
  252. wp_trash_post( $forum_id ); 
  253.  
  254. // Force view=all 
  255. $view_all = true; 
  256.  
  257. /** Spam Check ********************************************************/ 
  258.  
  259. // If reply or forum are spam, officially spam this reply 
  260. if ( $forum_data['post_status'] === bbp_get_spam_status_id() ) { 
  261. add_post_meta( $forum_id, '_bbp_spam_meta_status', bbp_get_public_status_id() ); 
  262.  
  263. // Force view=all 
  264. $view_all = true; 
  265.  
  266. /** Update counts, etc... *********************************************/ 
  267.  
  268. do_action( 'bbp_new_forum', array( 
  269. 'forum_id' => $forum_id,  
  270. 'post_parent' => $forum_parent_id,  
  271. 'forum_author' => $forum_author,  
  272. 'last_topic_id' => 0,  
  273. 'last_reply_id' => 0,  
  274. 'last_active_id' => 0,  
  275. 'last_active_time' => 0,  
  276. 'last_active_status' => bbp_get_public_status_id() 
  277. ) ); 
  278.  
  279. /** Additional Actions (After Save) ***********************************/ 
  280.  
  281. do_action( 'bbp_new_forum_post_extras', $forum_id ); 
  282.  
  283. /** Redirect **********************************************************/ 
  284.  
  285. // Redirect to 
  286. $redirect_to = bbp_get_redirect_to(); 
  287.  
  288. // Get the forum URL 
  289. $redirect_url = bbp_get_forum_permalink( $forum_id, $redirect_to ); 
  290.  
  291. // Add view all? 
  292. if ( bbp_get_view_all() || !empty( $view_all ) ) { 
  293.  
  294. // User can moderate, so redirect to forum with view all set 
  295. if ( current_user_can( 'moderate' ) ) { 
  296. $redirect_url = bbp_add_view_all( $redirect_url ); 
  297.  
  298. // User cannot moderate, so redirect to forum 
  299. } else { 
  300. $redirect_url = bbp_get_forum_permalink( $forum_id ); 
  301.  
  302. // Allow to be filtered 
  303. $redirect_url = apply_filters( 'bbp_new_forum_redirect_to', $redirect_url, $redirect_to ); 
  304.  
  305. /** Successful Save ***************************************************/ 
  306.  
  307. // Redirect back to new forum 
  308. wp_safe_redirect( $redirect_url ); 
  309.  
  310. // For good measure 
  311. exit(); 
  312.  
  313. // Errors 
  314. } else { 
  315. $append_error = ( is_wp_error( $forum_id ) && $forum_id->get_error_message() ) ? $forum_id->get_error_message() . ' ' : ''; 
  316. bbp_add_error( 'bbp_forum_error', __( '<strong>ERROR</strong>: The following problem(s) have been found with your forum:' . $append_error, 'bbpress' ) ); 
  317.  
  318. /** 
  319. * Handles the front end edit forum submission 
  320. * 
  321. * @param string $action The requested action to compare this function to 
  322. * @uses bbPress:errors::add() To log various error messages 
  323. * @uses bbp_get_forum() To get the forum 
  324. * @uses bbp_verify_nonce_request() To verify the nonce and check the request 
  325. * @uses bbp_is_forum_anonymous() To check if forum is by an anonymous user 
  326. * @uses current_user_can() To check if the current user can edit the forum 
  327. * @uses bbp_filter_anonymous_post_data() To filter anonymous data 
  328. * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error} 
  329. * @uses esc_attr() For sanitization 
  330. * @uses bbp_is_forum_category() To check if the forum is a category 
  331. * @uses bbp_is_forum_closed() To check if the forum is closed 
  332. * @uses bbp_is_forum_private() To check if the forum is private 
  333. * @uses remove_filter() To remove kses filters if needed 
  334. * @uses apply_filters() Calls 'bbp_edit_forum_pre_title' with the title and 
  335. * forum id 
  336. * @uses apply_filters() Calls 'bbp_edit_forum_pre_content' with the content 
  337. * and forum id 
  338. * @uses bbPress::errors::get_error_codes() To get the {@link WP_Error} errors 
  339. * @uses wp_save_post_revision() To save a forum revision 
  340. * @uses bbp_update_forum_revision_log() To update the forum revision log 
  341. * @uses wp_update_post() To update the forum 
  342. * @uses do_action() Calls 'bbp_edit_forum' with the forum id, forum id,  
  343. * anonymous data and reply author 
  344. * @uses bbp_move_forum_handler() To handle movement of a forum from one forum 
  345. * to another 
  346. * @uses bbp_get_forum_permalink() To get the forum permalink 
  347. * @uses wp_safe_redirect() To redirect to the forum link 
  348. * @uses bbPress::errors::get_error_messages() To get the {@link WP_Error} error 
  349. * messages 
  350. */ 
  351. function bbp_edit_forum_handler( $action = '' ) { 
  352.  
  353. // Bail if action is not bbp-edit-forum 
  354. if ( 'bbp-edit-forum' !== $action ) 
  355. return; 
  356.  
  357. // Define local variable(s) 
  358. $anonymous_data = array(); 
  359. $forum = $forum_id = $forum_parent_id = 0; 
  360. $forum_title = $forum_content = $forum_edit_reason = ''; 
  361.  
  362. /** Forum *****************************************************************/ 
  363.  
  364. // Forum id was not passed 
  365. if ( empty( $_POST['bbp_forum_id'] ) ) { 
  366. bbp_add_error( 'bbp_edit_forum_id', __( '<strong>ERROR</strong>: Forum ID not found.', 'bbpress' ) ); 
  367. return; 
  368.  
  369. // Forum id was passed 
  370. } elseif ( is_numeric( $_POST['bbp_forum_id'] ) ) { 
  371. $forum_id = (int) $_POST['bbp_forum_id']; 
  372. $forum = bbp_get_forum( $forum_id ); 
  373.  
  374. // Nonce check 
  375. if ( ! bbp_verify_nonce_request( 'bbp-edit-forum_' . $forum_id ) ) { 
  376. bbp_add_error( 'bbp_edit_forum_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) ); 
  377. return; 
  378.  
  379. // Forum does not exist 
  380. } elseif ( empty( $forum ) ) { 
  381. bbp_add_error( 'bbp_edit_forum_not_found', __( '<strong>ERROR</strong>: The forum you want to edit was not found.', 'bbpress' ) ); 
  382. return; 
  383.  
  384. // User cannot edit this forum 
  385. } elseif ( !current_user_can( 'edit_forum', $forum_id ) ) { 
  386. bbp_add_error( 'bbp_edit_forum_permissions', __( '<strong>ERROR</strong>: You do not have permission to edit that forum.', 'bbpress' ) ); 
  387. return; 
  388.  
  389. // Remove kses filters from title and content for capable users and if the nonce is verified 
  390. if ( current_user_can( 'unfiltered_html' ) && !empty( $_POST['_bbp_unfiltered_html_forum'] ) && ( wp_create_nonce( 'bbp-unfiltered-html-forum_' . $forum_id ) === $_POST['_bbp_unfiltered_html_forum'] ) ) { 
  391. remove_filter( 'bbp_edit_forum_pre_title', 'wp_filter_kses' ); 
  392. remove_filter( 'bbp_edit_forum_pre_content', 'bbp_encode_bad', 10 ); 
  393. remove_filter( 'bbp_edit_forum_pre_content', 'bbp_filter_kses', 30 ); 
  394.  
  395. /** Forum Parent ***********************************************************/ 
  396.  
  397. // Forum parent id was passed 
  398. if ( !empty( $_POST['bbp_forum_parent_id'] ) ) { 
  399. $forum_parent_id = bbp_get_forum_id( $_POST['bbp_forum_parent_id'] ); 
  400.  
  401. // Current forum this forum is in 
  402. $current_parent_forum_id = bbp_get_forum_parent_id( $forum_id ); 
  403.  
  404. // Forum exists 
  405. if ( !empty( $forum_parent_id ) && ( $forum_parent_id !== $current_parent_forum_id ) ) { 
  406.  
  407. // Forum is closed and user cannot access 
  408. if ( bbp_is_forum_closed( $forum_parent_id ) && !current_user_can( 'edit_forum', $forum_parent_id ) ) { 
  409. bbp_add_error( 'bbp_edit_forum_forum_closed', __( '<strong>ERROR</strong>: This forum has been closed to new forums.', 'bbpress' ) ); 
  410.  
  411. // Forum is private and user cannot access 
  412. if ( bbp_is_forum_private( $forum_parent_id ) && !current_user_can( 'read_private_forums' ) ) { 
  413. bbp_add_error( 'bbp_edit_forum_forum_private', __( '<strong>ERROR</strong>: This forum is private and you do not have the capability to read or create new forums in it.', 'bbpress' ) ); 
  414.  
  415. // Forum is hidden and user cannot access 
  416. if ( bbp_is_forum_hidden( $forum_parent_id ) && !current_user_can( 'read_hidden_forums' ) ) { 
  417. bbp_add_error( 'bbp_edit_forum_forum_hidden', __( '<strong>ERROR</strong>: This forum is hidden and you do not have the capability to read or create new forums in it.', 'bbpress' ) ); 
  418.  
  419. /** Forum Title ***********************************************************/ 
  420.  
  421. if ( !empty( $_POST['bbp_forum_title'] ) ) 
  422. $forum_title = esc_attr( strip_tags( $_POST['bbp_forum_title'] ) ); 
  423.  
  424. // Filter and sanitize 
  425. $forum_title = apply_filters( 'bbp_edit_forum_pre_title', $forum_title, $forum_id ); 
  426.  
  427. // No forum title 
  428. if ( empty( $forum_title ) ) 
  429. bbp_add_error( 'bbp_edit_forum_title', __( '<strong>ERROR</strong>: Your forum needs a title.', 'bbpress' ) ); 
  430.  
  431. /** Forum Content *********************************************************/ 
  432.  
  433. if ( !empty( $_POST['bbp_forum_content'] ) ) 
  434. $forum_content = $_POST['bbp_forum_content']; 
  435.  
  436. // Filter and sanitize 
  437. $forum_content = apply_filters( 'bbp_edit_forum_pre_content', $forum_content, $forum_id ); 
  438.  
  439. // No forum content 
  440. if ( empty( $forum_content ) ) 
  441. bbp_add_error( 'bbp_edit_forum_content', __( '<strong>ERROR</strong>: Your forum description cannot be empty.', 'bbpress' ) ); 
  442.  
  443. /** Forum Blacklist *******************************************************/ 
  444.  
  445. if ( !bbp_check_for_blacklist( $anonymous_data, bbp_get_forum_author_id( $forum_id ), $forum_title, $forum_content ) ) 
  446. bbp_add_error( 'bbp_forum_blacklist', __( '<strong>ERROR</strong>: Your forum cannot be edited at this time.', 'bbpress' ) ); 
  447.  
  448. /** Forum Moderation ******************************************************/ 
  449.  
  450. $post_status = bbp_get_public_status_id(); 
  451. if ( !bbp_check_for_moderation( $anonymous_data, bbp_get_forum_author_id( $forum_id ), $forum_title, $forum_content ) ) 
  452. $post_status = bbp_get_pending_status_id(); 
  453.  
  454. /** Additional Actions (Before Save) **************************************/ 
  455.  
  456. do_action( 'bbp_edit_forum_pre_extras', $forum_id ); 
  457.  
  458. // Bail if errors 
  459. if ( bbp_has_errors() ) 
  460. return; 
  461.  
  462. /** No Errors *************************************************************/ 
  463.  
  464. // Add the content of the form to $forum_data as an array 
  465. // Just in time manipulation of forum data before being edited 
  466. $forum_data = apply_filters( 'bbp_edit_forum_pre_insert', array( 
  467. 'ID' => $forum_id,  
  468. 'post_title' => $forum_title,  
  469. 'post_content' => $forum_content,  
  470. 'post_status' => $post_status,  
  471. 'post_parent' => $forum_parent_id 
  472. ) ); 
  473.  
  474. // Insert forum 
  475. $forum_id = wp_update_post( $forum_data ); 
  476.  
  477. /** Revisions *************************************************************/ 
  478.  
  479. /** 
  480. * @todo omitted for 2.1 
  481. // Revision Reason 
  482. if ( !empty( $_POST['bbp_forum_edit_reason'] ) ) 
  483. $forum_edit_reason = esc_attr( strip_tags( $_POST['bbp_forum_edit_reason'] ) ); 
  484.   
  485. // Update revision log 
  486. if ( !empty( $_POST['bbp_log_forum_edit'] ) && ( "1" === $_POST['bbp_log_forum_edit'] ) && ( $revision_id = wp_save_post_revision( $forum_id ) ) ) { 
  487. bbp_update_forum_revision_log( array( 
  488. 'forum_id' => $forum_id,  
  489. 'revision_id' => $revision_id,  
  490. 'author_id' => bbp_get_current_user_id(),  
  491. 'reason' => $forum_edit_reason 
  492. ) ); 
  493. } 
  494. */ 
  495.  
  496. /** No Errors *************************************************************/ 
  497.  
  498. if ( !empty( $forum_id ) && !is_wp_error( $forum_id ) ) { 
  499.  
  500. // Update counts, etc... 
  501. do_action( 'bbp_edit_forum', array( 
  502. 'forum_id' => $forum_id,  
  503. 'post_parent' => $forum_parent_id,  
  504. 'forum_author' => $forum->post_author,  
  505. 'last_topic_id' => 0,  
  506. 'last_reply_id' => 0,  
  507. 'last_active_id' => 0,  
  508. 'last_active_time' => 0,  
  509. 'last_active_status' => bbp_get_public_status_id() 
  510. ) ); 
  511.  
  512. // If the new forum parent id is not equal to the old forum parent 
  513. // id, run the bbp_move_forum action and pass the forum's parent id 
  514. // as the first arg and new forum parent id as the second. 
  515. // @todo implement 
  516. //if ( $forum_id !== $forum->post_parent ) 
  517. // bbp_move_forum_handler( $forum_parent_id, $forum->post_parent, $forum_id ); 
  518.  
  519. /** Additional Actions (After Save) ***********************************/ 
  520.  
  521. do_action( 'bbp_edit_forum_post_extras', $forum_id ); 
  522.  
  523. /** Redirect **********************************************************/ 
  524.  
  525. // Redirect to 
  526. $redirect_to = bbp_get_redirect_to(); 
  527.  
  528. // View all? 
  529. $view_all = bbp_get_view_all(); 
  530.  
  531. // Get the forum URL 
  532. $forum_url = bbp_get_forum_permalink( $forum_id, $redirect_to ); 
  533.  
  534. // Add view all? 
  535. if ( !empty( $view_all ) ) 
  536. $forum_url = bbp_add_view_all( $forum_url ); 
  537.  
  538. // Allow to be filtered 
  539. $forum_url = apply_filters( 'bbp_edit_forum_redirect_to', $forum_url, $view_all, $redirect_to ); 
  540.  
  541. /** Successful Edit ***************************************************/ 
  542.  
  543. // Redirect back to new forum 
  544. wp_safe_redirect( $forum_url ); 
  545.  
  546. // For good measure 
  547. exit(); 
  548.  
  549. /** Errors ****************************************************************/ 
  550.  
  551. } else { 
  552. $append_error = ( is_wp_error( $forum_id ) && $forum_id->get_error_message() ) ? $forum_id->get_error_message() . ' ' : ''; 
  553. bbp_add_error( 'bbp_forum_error', __( '<strong>ERROR</strong>: The following problem(s) have been found with your forum:' . $append_error . 'Please try again.', 'bbpress' ) ); 
  554.  
  555. /** 
  556. * Handle the saving of core forum metadata (Status, Visibility, and Type) 
  557. * 
  558. * @since bbPress (r3678) 
  559. * @param int $forum_id 
  560. * @uses bbp_is_forum_closed() To check if forum is closed 
  561. * @uses bbp_close_forum() To close forum 
  562. * @uses bbp_open_forum() To open forum 
  563. * @uses bbp_is_forum_category() To check if forum is a category 
  564. * @uses bbp_categorize_forum() To turn forum into a category 
  565. * @uses bbp_normalize_forum() To turn category into forum 
  566. * @uses bbp_get_public_status_id() To get the public status ID 
  567. * @uses bbp_get_private_status_id() To get the private status ID 
  568. * @uses bbp_get_hidden_status_id() To get the hidden status ID 
  569. * @uses bbp_get_forum_visibility() To get the forums visibility 
  570. * @uses bbp_hide_forum() To hide a forum 
  571. * @uses bbp_privatize_forum() To make a forum private 
  572. * @uses bbp_publicize_forum() To make a forum public 
  573. * @return If forum ID is empty 
  574. */ 
  575. function bbp_save_forum_extras( $forum_id = 0 ) { 
  576.  
  577. // Validate the forum ID 
  578. $forum_id = bbp_get_forum_id( $forum_id ); 
  579.  
  580. // Bail if forum ID is empty 
  581. if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) 
  582. return; 
  583.  
  584. /** Forum Status ******************************************************/ 
  585.  
  586. if ( !empty( $_POST['bbp_forum_status'] ) && in_array( $_POST['bbp_forum_status'], array( 'open', 'closed' ) ) ) { 
  587. if ( 'closed' === $_POST['bbp_forum_status'] && !bbp_is_forum_closed( $forum_id, false ) ) { 
  588. bbp_close_forum( $forum_id ); 
  589. } elseif ( 'open' === $_POST['bbp_forum_status'] && bbp_is_forum_closed( $forum_id, false ) ) { 
  590. bbp_open_forum( $forum_id ); 
  591.  
  592. /** Forum Type ********************************************************/ 
  593.  
  594. if ( !empty( $_POST['bbp_forum_type'] ) && in_array( $_POST['bbp_forum_type'], array( 'forum', 'category' ) ) ) { 
  595. if ( 'category' === $_POST['bbp_forum_type'] && !bbp_is_forum_category( $forum_id ) ) { 
  596. bbp_categorize_forum( $forum_id ); 
  597. } elseif ( 'forum' === $_POST['bbp_forum_type'] && bbp_is_forum_category( $forum_id ) ) { 
  598. bbp_normalize_forum( $forum_id ); 
  599.  
  600. /** Forum Visibility **************************************************/ 
  601.  
  602. if ( !empty( $_POST['bbp_forum_visibility'] ) && in_array( $_POST['bbp_forum_visibility'], array( bbp_get_public_status_id(), bbp_get_private_status_id(), bbp_get_hidden_status_id() ) ) ) { 
  603.  
  604. // Get forums current visibility 
  605. $visibility = bbp_get_forum_visibility( $forum_id ); 
  606.  
  607. // What is the new forum visibility setting? 
  608. switch ( $_POST['bbp_forum_visibility'] ) { 
  609.  
  610. // Hidden 
  611. case bbp_get_hidden_status_id() : 
  612. bbp_hide_forum( $forum_id, $visibility ); 
  613. break; 
  614.  
  615. // Private 
  616. case bbp_get_private_status_id() : 
  617. bbp_privatize_forum( $forum_id, $visibility ); 
  618. break; 
  619.  
  620. // Publish (default) 
  621. case bbp_get_public_status_id() : 
  622. default : 
  623. bbp_publicize_forum( $forum_id, $visibility ); 
  624. break; 
  625.  
  626. /** Forum Actions *************************************************************/ 
  627.  
  628. /** 
  629. * Closes a forum 
  630. * 
  631. * @since bbPress (r2746) 
  632. * 
  633. * @param int $forum_id forum id 
  634. * @uses do_action() Calls 'bbp_close_forum' with the forum id 
  635. * @uses update_post_meta() To add the previous status to a meta 
  636. * @uses do_action() Calls 'bbp_opened_forum' with the forum id 
  637. * @return mixed False or {@link WP_Error} on failure, forum id on success 
  638. */ 
  639. function bbp_close_forum( $forum_id = 0 ) { 
  640.  
  641. $forum_id = bbp_get_forum_id( $forum_id ); 
  642.  
  643. do_action( 'bbp_close_forum', $forum_id ); 
  644.  
  645. update_post_meta( $forum_id, '_bbp_status', 'closed' ); 
  646.  
  647. do_action( 'bbp_closed_forum', $forum_id ); 
  648.  
  649. return $forum_id; 
  650.  
  651. /** 
  652. * Opens a forum 
  653. * 
  654. * @since bbPress (r2746) 
  655. * 
  656. * @param int $forum_id forum id 
  657. * @uses do_action() Calls 'bbp_open_forum' with the forum id 
  658. * @uses get_post_meta() To get the previous status 
  659. * @uses update_post_meta() To delete the previous status meta 
  660. * @uses do_action() Calls 'bbp_opened_forum' with the forum id 
  661. * @return mixed False or {@link WP_Error} on failure, forum id on success 
  662. */ 
  663. function bbp_open_forum( $forum_id = 0 ) { 
  664.  
  665. $forum_id = bbp_get_forum_id( $forum_id ); 
  666.  
  667. do_action( 'bbp_open_forum', $forum_id ); 
  668.  
  669. update_post_meta( $forum_id, '_bbp_status', 'open' ); 
  670.  
  671. do_action( 'bbp_opened_forum', $forum_id ); 
  672.  
  673. return $forum_id; 
  674.  
  675. /** 
  676. * Make the forum a category 
  677. * 
  678. * @since bbPress (r2746) 
  679. * 
  680. * @param int $forum_id Optional. Forum id 
  681. * @uses update_post_meta() To update the forum category meta 
  682. * @return bool False on failure, true on success 
  683. */ 
  684. function bbp_categorize_forum( $forum_id = 0 ) { 
  685.  
  686. $forum_id = bbp_get_forum_id( $forum_id ); 
  687.  
  688. do_action( 'bbp_categorize_forum', $forum_id ); 
  689.  
  690. update_post_meta( $forum_id, '_bbp_forum_type', 'category' ); 
  691.  
  692. do_action( 'bbp_categorized_forum', $forum_id ); 
  693.  
  694. return $forum_id; 
  695.  
  696. /** 
  697. * Remove the category status from a forum 
  698. * 
  699. * @since bbPress (r2746) 
  700. * 
  701. * @param int $forum_id Optional. Forum id 
  702. * @uses delete_post_meta() To delete the forum category meta 
  703. * @return bool False on failure, true on success 
  704. */ 
  705. function bbp_normalize_forum( $forum_id = 0 ) { 
  706.  
  707. $forum_id = bbp_get_forum_id( $forum_id ); 
  708.  
  709. do_action( 'bbp_normalize_forum', $forum_id ); 
  710.  
  711. update_post_meta( $forum_id, '_bbp_forum_type', 'forum' ); 
  712.  
  713. do_action( 'bbp_normalized_forum', $forum_id ); 
  714.  
  715. return $forum_id; 
  716.  
  717. /** 
  718. * Mark the forum as public 
  719. * 
  720. * @since bbPress (r2746) 
  721. * 
  722. * @param int $forum_id Optional. Forum id 
  723. * @uses update_post_meta() To update the forum private meta 
  724. * @return bool False on failure, true on success 
  725. */ 
  726. function bbp_publicize_forum( $forum_id = 0, $current_visibility = '' ) { 
  727.  
  728. $forum_id = bbp_get_forum_id( $forum_id ); 
  729.  
  730. do_action( 'bbp_publicize_forum', $forum_id ); 
  731.  
  732. // Get private forums 
  733. $private = bbp_get_private_forum_ids(); 
  734.  
  735. // Find this forum in the array 
  736. if ( in_array( $forum_id, $private ) ) { 
  737.  
  738. $offset = array_search( $forum_id, $private ); 
  739.  
  740. // Splice around it 
  741. array_splice( $private, $offset, 1 ); 
  742.  
  743. // Update private forums minus this one 
  744. update_option( '_bbp_private_forums', array_unique( array_filter( array_values( $private ) ) ) ); 
  745.  
  746. // Get hidden forums 
  747. $hidden = bbp_get_hidden_forum_ids(); 
  748.  
  749. // Find this forum in the array 
  750. if ( in_array( $forum_id, $hidden ) ) { 
  751.  
  752. $offset = array_search( $forum_id, $hidden ); 
  753.  
  754. // Splice around it 
  755. array_splice( $hidden, $offset, 1 ); 
  756.  
  757. // Update hidden forums minus this one 
  758. update_option( '_bbp_hidden_forums', array_unique( array_filter( array_values( $hidden ) ) ) ); 
  759.  
  760. // Only run queries if visibility is changing 
  761. if ( bbp_get_public_status_id() !== $current_visibility ) { 
  762.  
  763. // Update forums visibility setting 
  764. global $wpdb; 
  765. $wpdb->update( $wpdb->posts, array( 'post_status' => bbp_get_public_status_id() ), array( 'ID' => $forum_id ) ); 
  766. wp_transition_post_status( bbp_get_public_status_id(), $current_visibility, get_post( $forum_id ) ); 
  767. bbp_clean_post_cache( $forum_id ); 
  768.  
  769. do_action( 'bbp_publicized_forum', $forum_id ); 
  770.  
  771. return $forum_id; 
  772.  
  773. /** 
  774. * Mark the forum as private 
  775. * 
  776. * @since bbPress (r2746) 
  777. * 
  778. * @param int $forum_id Optional. Forum id 
  779. * @uses update_post_meta() To update the forum private meta 
  780. * @return bool False on failure, true on success 
  781. */ 
  782. function bbp_privatize_forum( $forum_id = 0, $current_visibility = '' ) { 
  783.  
  784. $forum_id = bbp_get_forum_id( $forum_id ); 
  785.  
  786. do_action( 'bbp_privatize_forum', $forum_id ); 
  787.  
  788. // Only run queries if visibility is changing 
  789. if ( bbp_get_private_status_id() !== $current_visibility ) { 
  790.  
  791. // Get hidden forums 
  792. $hidden = bbp_get_hidden_forum_ids(); 
  793.  
  794. // Find this forum in the array 
  795. if ( in_array( $forum_id, $hidden ) ) { 
  796.  
  797. $offset = array_search( $forum_id, $hidden ); 
  798.  
  799. // Splice around it 
  800. array_splice( $hidden, $offset, 1 ); 
  801.  
  802. // Update hidden forums minus this one 
  803. update_option( '_bbp_hidden_forums', array_unique( array_filter( array_values( $hidden ) ) ) ); 
  804.  
  805. // Add to '_bbp_private_forums' site option 
  806. $private = bbp_get_private_forum_ids(); 
  807. $private[] = $forum_id; 
  808. update_option( '_bbp_private_forums', array_unique( array_filter( array_values( $private ) ) ) ); 
  809.  
  810. // Update forums visibility setting 
  811. global $wpdb; 
  812. $wpdb->update( $wpdb->posts, array( 'post_status' => bbp_get_private_status_id() ), array( 'ID' => $forum_id ) ); 
  813. wp_transition_post_status( bbp_get_private_status_id(), $current_visibility, get_post( $forum_id ) ); 
  814. bbp_clean_post_cache( $forum_id ); 
  815.  
  816. do_action( 'bbp_privatized_forum', $forum_id ); 
  817.  
  818. return $forum_id; 
  819.  
  820. /** 
  821. * Mark the forum as hidden 
  822. * 
  823. * @since bbPress (r2996) 
  824. * 
  825. * @param int $forum_id Optional. Forum id 
  826. * @uses update_post_meta() To update the forum private meta 
  827. * @return bool False on failure, true on success 
  828. */ 
  829. function bbp_hide_forum( $forum_id = 0, $current_visibility = '' ) { 
  830.  
  831. $forum_id = bbp_get_forum_id( $forum_id ); 
  832.  
  833. do_action( 'bbp_hide_forum', $forum_id ); 
  834.  
  835. // Only run queries if visibility is changing 
  836. if ( bbp_get_hidden_status_id() !== $current_visibility ) { 
  837.  
  838. // Get private forums 
  839. $private = bbp_get_private_forum_ids(); 
  840.  
  841. // Find this forum in the array 
  842. if ( in_array( $forum_id, $private ) ) { 
  843.  
  844. $offset = array_search( $forum_id, $private ); 
  845.  
  846. // Splice around it 
  847. array_splice( $private, $offset, 1 ); 
  848.  
  849. // Update private forums minus this one 
  850. update_option( '_bbp_private_forums', array_unique( array_filter( array_values( $private ) ) ) ); 
  851.  
  852. // Add to '_bbp_hidden_forums' site option 
  853. $hidden = bbp_get_hidden_forum_ids(); 
  854. $hidden[] = $forum_id; 
  855. update_option( '_bbp_hidden_forums', array_unique( array_filter( array_values( $hidden ) ) ) ); 
  856.  
  857. // Update forums visibility setting 
  858. global $wpdb; 
  859. $wpdb->update( $wpdb->posts, array( 'post_status' => bbp_get_hidden_status_id() ), array( 'ID' => $forum_id ) ); 
  860. wp_transition_post_status( bbp_get_hidden_status_id(), $current_visibility, get_post( $forum_id ) ); 
  861. bbp_clean_post_cache( $forum_id ); 
  862.  
  863. do_action( 'bbp_hid_forum', $forum_id ); 
  864.  
  865. return $forum_id; 
  866.  
  867. /** 
  868. * Recaches the private and hidden forums 
  869. * 
  870. * @since bbPress (r5017) 
  871. * 
  872. * @uses delete_option() to delete private and hidden forum pointers 
  873. * @uses WP_Query() To query post IDs 
  874. * @uses is_wp_error() To return if error occurred 
  875. * @uses update_option() To update the private and hidden post ID pointers 
  876. * @return array An array of the status code and the message 
  877. */ 
  878. function bbp_repair_forum_visibility() { 
  879.  
  880. // First, delete everything. 
  881. delete_option( '_bbp_private_forums' ); 
  882. delete_option( '_bbp_hidden_forums' ); 
  883.  
  884. // Next, get all the private and hidden forums 
  885. $private_forums = new WP_Query( array( 
  886. 'suppress_filters' => true,  
  887. 'nopaging' => true,  
  888. 'post_type' => bbp_get_forum_post_type(),  
  889. 'post_status' => bbp_get_private_status_id(),  
  890. 'fields' => 'ids' 
  891. ) ); 
  892. $hidden_forums = new WP_Query( array( 
  893. 'suppress_filters' => true,  
  894. 'nopaging' => true,  
  895. 'post_type' => bbp_get_forum_post_type(),  
  896. 'post_status' => bbp_get_hidden_status_id(),  
  897. 'fields' => 'ids' 
  898. ) ); 
  899.  
  900. // Reset the $post global 
  901. wp_reset_postdata(); 
  902.  
  903. // Bail if queries returned errors 
  904. if ( is_wp_error( $private_forums ) || is_wp_error( $hidden_forums ) ) 
  905. return false; 
  906.  
  907. // Update the private/hidden options 
  908. update_option( '_bbp_private_forums', $private_forums->posts ); // Private forums 
  909. update_option( '_bbp_hidden_forums', $hidden_forums->posts ); // Hidden forums 
  910.  
  911. // Complete results 
  912. return true; 
  913.  
  914. /** Subscriptions *************************************************************/ 
  915.  
  916. /** 
  917. * Remove a deleted forum from all users' subscriptions 
  918. * 
  919. * @since bbPress (r5156) 
  920. * 
  921. * @param int $forum_id Get the forum ID to remove 
  922. * @uses bbp_is_subscriptions_active() To check if the subscriptions are active 
  923. * @uses bbp_get_forum_id To get the forum id 
  924. * @uses bbp_get_forum_subscribers() To get the forum subscribers 
  925. * @uses bbp_remove_user_subscription() To remove the user subscription 
  926. */ 
  927. function bbp_remove_forum_from_all_subscriptions( $forum_id = 0 ) { 
  928.  
  929. // Subscriptions are not active 
  930. if ( ! bbp_is_subscriptions_active() ) { 
  931. return; 
  932.  
  933. $forum_id = bbp_get_forum_id( $forum_id ); 
  934.  
  935. // Bail if no forum 
  936. if ( empty( $forum_id ) ) { 
  937. return; 
  938.  
  939. // Get users 
  940. $users = (array) bbp_get_forum_subscribers( $forum_id ); 
  941.  
  942. // Users exist 
  943. if ( !empty( $users ) ) { 
  944.  
  945. // Loop through users 
  946. foreach ( $users as $user ) { 
  947.  
  948. // Remove each user 
  949. bbp_remove_user_subscription( $user, $forum_id ); 
  950.  
  951. /** Count Bumpers *************************************************************/ 
  952.  
  953. /** 
  954. * Bump the total topic count of a forum 
  955. * 
  956. * @since bbPress (r3825) 
  957. * 
  958. * @param int $forum_id Optional. Forum id. 
  959. * @param int $difference Optional. Default 1 
  960. * @param bool $update_ancestors Optional. Default true 
  961. * @uses bbp_get_forum_id() To get the forum id 
  962. * @uses update_post_meta() To update the forum's topic count meta 
  963. * @uses apply_filters() Calls 'bbp_bump_forum_topic_count' with the topic 
  964. * count, forum id, and difference 
  965. * @return int Forum topic count 
  966. */ 
  967. function bbp_bump_forum_topic_count( $forum_id = 0, $difference = 1, $update_ancestors = true ) { 
  968.  
  969. // Get some counts 
  970. $forum_id = bbp_get_forum_id( $forum_id ); 
  971. $topic_count = bbp_get_forum_topic_count( $forum_id, false, true ); 
  972. $total_topic_count = bbp_get_forum_topic_count( $forum_id, true, true ); 
  973.  
  974. // Update this forum id 
  975. update_post_meta( $forum_id, '_bbp_topic_count', (int) $topic_count + (int) $difference ); 
  976. update_post_meta( $forum_id, '_bbp_total_topic_count', (int) $total_topic_count + (int) $difference ); 
  977.  
  978. // Check for ancestors 
  979. if ( true === $update_ancestors ) { 
  980.  
  981. // Get post ancestors 
  982. $forum = get_post( $forum_id ); 
  983. $ancestors = get_post_ancestors( $forum ); 
  984.  
  985. // If has ancestors, loop through them... 
  986. if ( !empty( $ancestors ) ) { 
  987. foreach ( (array) $ancestors as $parent_forum_id ) { 
  988.  
  989. // Get forum counts 
  990. $parent_topic_count = bbp_get_forum_topic_count( $parent_forum_id, false, true ); 
  991. $parent_total_topic_count = bbp_get_forum_topic_count( $parent_forum_id, true, true ); 
  992.  
  993. // Update counts 
  994. update_post_meta( $parent_forum_id, '_bbp_topic_count', (int) $parent_topic_count + (int) $difference ); 
  995. update_post_meta( $parent_forum_id, '_bbp_total_topic_count', (int) $parent_total_topic_count + (int) $difference ); 
  996.  
  997. return (int) apply_filters( 'bbp_bump_forum_topic_count', (int) $total_topic_count + (int) $difference, $forum_id, (int) $difference, (bool) $update_ancestors ); 
  998.  
  999. /** 
  1000. * Bump the total hidden topic count of a forum 
  1001. * 
  1002. * @since bbPress (r3825) 
  1003. * 
  1004. * @param int $forum_id Optional. Forum id. 
  1005. * @param int $difference Optional. Default 1 
  1006. * @uses bbp_get_forum_id() To get the forum id 
  1007. * @uses update_post_meta() To update the forum's topic count meta 
  1008. * @uses apply_filters() Calls 'bbp_bump_forum_topic_count_hidden' with the 
  1009. * topic count, forum id, and difference 
  1010. * @return int Forum hidden topic count 
  1011. */ 
  1012. function bbp_bump_forum_topic_count_hidden( $forum_id = 0, $difference = 1 ) { 
  1013.  
  1014. // Get some counts 
  1015. $forum_id = bbp_get_forum_id( $forum_id ); 
  1016. $topic_count = bbp_get_forum_topic_count_hidden( $forum_id, true ); 
  1017. $new_count = (int) $topic_count + (int) $difference; 
  1018.  
  1019. // Update this forum id 
  1020. update_post_meta( $forum_id, '_bbp_topic_count_hidden', (int) $new_count ); 
  1021.  
  1022. return (int) apply_filters( 'bbp_bump_forum_topic_count_hidden', (int) $new_count, $forum_id, (int) $difference ); 
  1023.  
  1024. /** 
  1025. * Bump the total topic count of a forum 
  1026. * 
  1027. * @since bbPress (r3825) 
  1028. * 
  1029. * @param int $forum_id Optional. Forum id. 
  1030. * @param int $difference Optional. Default 1 
  1031. * @param bool $update_ancestors Optional. Default true 
  1032. * @uses bbp_get_forum_id() To get the forum id 
  1033. * @uses update_post_meta() To update the forum's topic count meta 
  1034. * @uses apply_filters() Calls 'bbp_bump_forum_reply_count' with the topic 
  1035. * count, forum id, and difference 
  1036. * @return int Forum topic count 
  1037. */ 
  1038. function bbp_bump_forum_reply_count( $forum_id = 0, $difference = 1, $update_ancestors = true ) { 
  1039.  
  1040. // Get some counts 
  1041. $forum_id = bbp_get_forum_id( $forum_id ); 
  1042. $topic_count = bbp_get_forum_reply_count( $forum_id, false, true ); 
  1043. $total_reply_count = bbp_get_forum_reply_count( $forum_id, true, true ); 
  1044.  
  1045. // Update this forum id 
  1046. update_post_meta( $forum_id, '_bbp_reply_count', (int) $topic_count + (int) $difference ); 
  1047. update_post_meta( $forum_id, '_bbp_total_reply_count', (int) $total_reply_count + (int) $difference ); 
  1048.  
  1049. // Check for ancestors 
  1050. if ( true === $update_ancestors ) { 
  1051.  
  1052. // Get post ancestors 
  1053. $forum = get_post( $forum_id ); 
  1054. $ancestors = get_post_ancestors( $forum ); 
  1055.  
  1056. // If has ancestors, loop through them... 
  1057. if ( !empty( $ancestors ) ) { 
  1058. foreach ( (array) $ancestors as $parent_forum_id ) { 
  1059.  
  1060. // Get forum counts 
  1061. $parent_topic_count = bbp_get_forum_reply_count( $parent_forum_id, false, true ); 
  1062. $parent_total_reply_count = bbp_get_forum_reply_count( $parent_forum_id, true, true ); 
  1063.  
  1064. // Update counts 
  1065. update_post_meta( $parent_forum_id, '_bbp_reply_count', (int) $parent_topic_count + (int) $difference ); 
  1066. update_post_meta( $parent_forum_id, '_bbp_total_reply_count', (int) $parent_total_reply_count + (int) $difference ); 
  1067.  
  1068. return (int) apply_filters( 'bbp_bump_forum_reply_count', (int) $total_reply_count + (int) $difference, $forum_id, (int) $difference, (bool) $update_ancestors ); 
  1069.  
  1070. /** Forum Updaters ************************************************************/ 
  1071.  
  1072. /** 
  1073. * Update the forum last topic id 
  1074. * 
  1075. * @since bbPress (r2625) 
  1076. * 
  1077. * @param int $forum_id Optional. Forum id 
  1078. * @param int $topic_id Optional. Topic id 
  1079. * @uses bbp_get_forum_id() To get the forum id 
  1080. * @uses bbp_forum_query_subforum_ids() To get the subforum ids 
  1081. * @uses bbp_update_forum_last_topic_id() To update the last topic id of child 
  1082. * forums 
  1083. * @uses get_posts() To get the most recent topic in the forum 
  1084. * @uses update_post_meta() To update the forum's last active id meta 
  1085. * @uses apply_filters() Calls 'bbp_update_forum_last_topic_id' with the last 
  1086. * reply id and forum id 
  1087. * @return bool True on success, false on failure 
  1088. */ 
  1089. function bbp_update_forum_last_topic_id( $forum_id = 0, $topic_id = 0 ) { 
  1090. $forum_id = bbp_get_forum_id( $forum_id ); 
  1091.  
  1092. // Define local variable(s) 
  1093. $children_last_topic = 0; 
  1094.  
  1095. // Do some calculation if not manually set 
  1096. if ( empty( $topic_id ) ) { 
  1097.  
  1098. // Loop through children and add together forum reply counts 
  1099. $children = bbp_forum_query_subforum_ids( $forum_id ); 
  1100. if ( !empty( $children ) ) { 
  1101. foreach ( (array) $children as $child ) { 
  1102. $children_last_topic = bbp_update_forum_last_topic_id( $child ); // Recursive 
  1103.  
  1104. // Setup recent topic query vars 
  1105. $post_vars = array( 
  1106. 'post_parent' => $forum_id,  
  1107. 'post_type' => bbp_get_topic_post_type(),  
  1108. 'meta_key' => '_bbp_last_active_time',  
  1109. 'orderby' => 'meta_value',  
  1110. 'numberposts' => 1 
  1111. ); 
  1112.  
  1113. // Get the most recent topic in this forum_id 
  1114. $recent_topic = get_posts( $post_vars ); 
  1115. if ( !empty( $recent_topic ) ) { 
  1116. $topic_id = $recent_topic[0]->ID; 
  1117.  
  1118. // Cast as integer in case of empty or string 
  1119. $topic_id = (int) $topic_id; 
  1120. $children_last_topic = (int) $children_last_topic; 
  1121.  
  1122. // If child forums have higher id, use that instead 
  1123. if ( !empty( $children ) && ( $children_last_topic > $topic_id ) ) 
  1124. $topic_id = $children_last_topic; 
  1125.  
  1126. // Update the last public topic ID 
  1127. if ( bbp_is_topic_published( $topic_id ) ) 
  1128. update_post_meta( $forum_id, '_bbp_last_topic_id', $topic_id ); 
  1129.  
  1130. return (int) apply_filters( 'bbp_update_forum_last_topic_id', $topic_id, $forum_id ); 
  1131.  
  1132. /** 
  1133. * Update the forum last reply id 
  1134. * 
  1135. * @since bbPress (r2625) 
  1136. * 
  1137. * @param int $forum_id Optional. Forum id 
  1138. * @param int $reply_id Optional. Reply id 
  1139. * @uses bbp_get_forum_id() To get the forum id 
  1140. * @uses bbp_forum_query_subforum_ids() To get the subforum ids 
  1141. * @uses bbp_update_forum_last_reply_id() To update the last reply id of child 
  1142. * forums 
  1143. * @uses bbp_forum_query_topic_ids() To get the topic ids in the forum 
  1144. * @uses bbp_forum_query_last_reply_id() To get the forum's last reply id 
  1145. * @uses bbp_is_reply_published() To make sure the reply is published 
  1146. * @uses update_post_meta() To update the forum's last active id meta 
  1147. * @uses apply_filters() Calls 'bbp_update_forum_last_reply_id' with the last 
  1148. * reply id and forum id 
  1149. * @return bool True on success, false on failure 
  1150. */ 
  1151. function bbp_update_forum_last_reply_id( $forum_id = 0, $reply_id = 0 ) { 
  1152. $forum_id = bbp_get_forum_id( $forum_id ); 
  1153.  
  1154. // Define local variable(s) 
  1155. $children_last_reply = 0; 
  1156.  
  1157. // Do some calculation if not manually set 
  1158. if ( empty( $reply_id ) ) { 
  1159.  
  1160. // Loop through children and get the most recent reply id 
  1161. $children = bbp_forum_query_subforum_ids( $forum_id ); 
  1162. if ( !empty( $children ) ) { 
  1163. foreach ( (array) $children as $child ) { 
  1164. $children_last_reply = bbp_update_forum_last_reply_id( $child ); // Recursive 
  1165.  
  1166. // If this forum has topics... 
  1167. $topic_ids = bbp_forum_query_topic_ids( $forum_id ); 
  1168. if ( !empty( $topic_ids ) ) { 
  1169.  
  1170. // ...get the most recent reply from those topics... 
  1171. $reply_id = bbp_forum_query_last_reply_id( $forum_id, $topic_ids ); 
  1172.  
  1173. // ...and compare it to the most recent topic id... 
  1174. $reply_id = ( $reply_id > max( $topic_ids ) ) ? $reply_id : max( $topic_ids ); 
  1175.  
  1176. // Cast as integer in case of empty or string 
  1177. $reply_id = (int) $reply_id; 
  1178. $children_last_reply = (int) $children_last_reply; 
  1179.  
  1180. // If child forums have higher ID, check for newer reply id 
  1181. if ( !empty( $children ) && ( $children_last_reply > $reply_id ) ) 
  1182. $reply_id = $children_last_reply; 
  1183.  
  1184. // Update the last public reply ID 
  1185. if ( bbp_is_reply_published( $reply_id ) ) 
  1186. update_post_meta( $forum_id, '_bbp_last_reply_id', $reply_id ); 
  1187.  
  1188. return (int) apply_filters( 'bbp_update_forum_last_reply_id', $reply_id, $forum_id ); 
  1189.  
  1190. /** 
  1191. * Update the forum last active post id 
  1192. * 
  1193. * @since bbPress (r2860) 
  1194. * 
  1195. * @param int $forum_id Optional. Forum id 
  1196. * @param int $active_id Optional. Active post id 
  1197. * @uses bbp_get_forum_id() To get the forum id 
  1198. * @uses bbp_forum_query_subforum_ids() To get the subforum ids 
  1199. * @uses bbp_update_forum_last_active_id() To update the last active id of 
  1200. * child forums 
  1201. * @uses bbp_forum_query_topic_ids() To get the topic ids in the forum 
  1202. * @uses bbp_forum_query_last_reply_id() To get the forum's last reply id 
  1203. * @uses get_post_status() To make sure the reply is published 
  1204. * @uses update_post_meta() To update the forum's last active id meta 
  1205. * @uses apply_filters() Calls 'bbp_update_forum_last_active_id' with the last 
  1206. * active post id and forum id 
  1207. * @return bool True on success, false on failure 
  1208. */ 
  1209. function bbp_update_forum_last_active_id( $forum_id = 0, $active_id = 0 ) { 
  1210.  
  1211. $forum_id = bbp_get_forum_id( $forum_id ); 
  1212.  
  1213. // Define local variable(s) 
  1214. $children_last_active = 0; 
  1215.  
  1216. // Do some calculation if not manually set 
  1217. if ( empty( $active_id ) ) { 
  1218.  
  1219. // Loop through children and add together forum reply counts 
  1220. $children = bbp_forum_query_subforum_ids( $forum_id ); 
  1221. if ( !empty( $children ) ) { 
  1222. foreach ( (array) $children as $child ) { 
  1223. $children_last_active = bbp_update_forum_last_active_id( $child, $active_id ); 
  1224.  
  1225. // Don't count replies if the forum is a category 
  1226. $topic_ids = bbp_forum_query_topic_ids( $forum_id ); 
  1227. if ( !empty( $topic_ids ) ) { 
  1228. $active_id = bbp_forum_query_last_reply_id( $forum_id, $topic_ids ); 
  1229. $active_id = $active_id > max( $topic_ids ) ? $active_id : max( $topic_ids ); 
  1230.  
  1231. // Forum has no topics 
  1232. } else { 
  1233. $active_id = 0; 
  1234.  
  1235. // Cast as integer in case of empty or string 
  1236. $active_id = (int) $active_id; 
  1237. $children_last_active = (int) $children_last_active; 
  1238.  
  1239. // If child forums have higher id, use that instead 
  1240. if ( !empty( $children ) && ( $children_last_active > $active_id ) ) 
  1241. $active_id = $children_last_active; 
  1242.  
  1243. // Update only if published 
  1244. if ( bbp_get_public_status_id() === get_post_status( $active_id ) ) 
  1245. update_post_meta( $forum_id, '_bbp_last_active_id', (int) $active_id ); 
  1246.  
  1247. return (int) apply_filters( 'bbp_update_forum_last_active_id', (int) $active_id, $forum_id ); 
  1248.  
  1249. /** 
  1250. * Update the forums last active date/time (aka freshness) 
  1251. * 
  1252. * @since bbPress (r2680) 
  1253. * 
  1254. * @param int $forum_id Optional. Topic id 
  1255. * @param string $new_time Optional. New time in mysql format 
  1256. * @uses bbp_get_forum_id() To get the forum id 
  1257. * @uses bbp_get_forum_last_active_id() To get the forum's last post id 
  1258. * @uses get_post_field() To get the post date of the forum's last post 
  1259. * @uses update_post_meta() To update the forum last active time 
  1260. * @uses apply_filters() Calls 'bbp_update_forum_last_active' with the new time 
  1261. * and forum id 
  1262. * @return bool True on success, false on failure 
  1263. */ 
  1264. function bbp_update_forum_last_active_time( $forum_id = 0, $new_time = '' ) { 
  1265. $forum_id = bbp_get_forum_id( $forum_id ); 
  1266.  
  1267. // Check time and use current if empty 
  1268. if ( empty( $new_time ) ) 
  1269. $new_time = get_post_field( 'post_date', bbp_get_forum_last_active_id( $forum_id ) ); 
  1270.  
  1271. // Update only if there is a time 
  1272. if ( !empty( $new_time ) ) 
  1273. update_post_meta( $forum_id, '_bbp_last_active_time', $new_time ); 
  1274.  
  1275. return (int) apply_filters( 'bbp_update_forum_last_active', $new_time, $forum_id ); 
  1276.  
  1277. /** 
  1278. * Update the forum sub-forum count 
  1279. * 
  1280. * @since bbPress (r2625) 
  1281. * 
  1282. * @param int $forum_id Optional. Forum id 
  1283. * @uses bbp_get_forum_id() To get the forum id 
  1284. * @return bool True on success, false on failure 
  1285. */ 
  1286. function bbp_update_forum_subforum_count( $forum_id = 0, $subforums = 0 ) { 
  1287. $forum_id = bbp_get_forum_id( $forum_id ); 
  1288.  
  1289. if ( empty( $subforums ) ) 
  1290. $subforums = count( bbp_forum_query_subforum_ids( $forum_id ) ); 
  1291.  
  1292. update_post_meta( $forum_id, '_bbp_forum_subforum_count', (int) $subforums ); 
  1293.  
  1294. return (int) apply_filters( 'bbp_update_forum_subforum_count', (int) $subforums, $forum_id ); 
  1295.  
  1296. /** 
  1297. * Adjust the total topic count of a forum 
  1298. * 
  1299. * @since bbPress (r2464) 
  1300. * 
  1301. * @param int $forum_id Optional. Forum id or topic id. It is checked whether it 
  1302. * is a topic or a forum. If it's a topic, its parent,  
  1303. * i.e. the forum is automatically retrieved. 
  1304. * @param bool $total_count Optional. To return the total count or normal 
  1305. * count? 
  1306. * @uses bbp_get_forum_id() To get the forum id 
  1307. * @uses bbp_forum_query_subforum_ids() To get the subforum ids 
  1308. * @uses bbp_update_forum_topic_count() To update the forum topic count 
  1309. * @uses bbp_forum_query_topic_ids() To get the forum topic ids 
  1310. * @uses update_post_meta() To update the forum's topic count meta 
  1311. * @uses apply_filters() Calls 'bbp_update_forum_topic_count' with the topic 
  1312. * count and forum id 
  1313. * @return int Forum topic count 
  1314. */ 
  1315. function bbp_update_forum_topic_count( $forum_id = 0 ) { 
  1316. $forum_id = bbp_get_forum_id( $forum_id ); 
  1317. $children_topic_count = 0; 
  1318.  
  1319. // Loop through subforums and add together forum topic counts 
  1320. $children = bbp_forum_query_subforum_ids( $forum_id ); 
  1321. if ( !empty( $children ) ) { 
  1322. foreach ( (array) $children as $child ) { 
  1323. $children_topic_count += bbp_update_forum_topic_count( $child ); // Recursive 
  1324.  
  1325. // Get total topics for this forum 
  1326. $topics = (int) count( bbp_forum_query_topic_ids( $forum_id ) ); 
  1327.  
  1328. // Calculate total topics in this forum 
  1329. $total_topics = $topics + $children_topic_count; 
  1330.  
  1331. // Update the count 
  1332. update_post_meta( $forum_id, '_bbp_topic_count', (int) $topics ); 
  1333. update_post_meta( $forum_id, '_bbp_total_topic_count', (int) $total_topics ); 
  1334.  
  1335. return (int) apply_filters( 'bbp_update_forum_topic_count', (int) $total_topics, $forum_id ); 
  1336.  
  1337. /** 
  1338. * Adjust the total hidden topic count of a forum (hidden includes trashed and spammed topics) 
  1339. * 
  1340. * @since bbPress (r2888) 
  1341. * 
  1342. * @param int $forum_id Optional. Topic id to update 
  1343. * @param int $topic_count Optional. Set the topic count manually 
  1344. * @uses bbp_is_topic() To check if the supplied id is a topic 
  1345. * @uses bbp_get_topic_id() To get the topic id 
  1346. * @uses bbp_get_topic_forum_id() To get the topic forum id 
  1347. * @uses bbp_get_forum_id() To get the forum id 
  1348. * @uses wpdb::prepare() To prepare our sql query 
  1349. * @uses wpdb::get_col() To execute our query and get the column back 
  1350. * @uses update_post_meta() To update the forum hidden topic count meta 
  1351. * @uses apply_filters() Calls 'bbp_update_forum_topic_count_hidden' with the 
  1352. * hidden topic count and forum id 
  1353. * @return int Topic hidden topic count 
  1354. */ 
  1355. function bbp_update_forum_topic_count_hidden( $forum_id = 0, $topic_count = 0 ) { 
  1356. global $wpdb; 
  1357.  
  1358. // If topic_id was passed as $forum_id, then get its forum 
  1359. if ( bbp_is_topic( $forum_id ) ) { 
  1360. $topic_id = bbp_get_topic_id( $forum_id ); 
  1361. $forum_id = bbp_get_topic_forum_id( $topic_id ); 
  1362.  
  1363. // $forum_id is not a topic_id, so validate and proceed 
  1364. } else { 
  1365. $forum_id = bbp_get_forum_id( $forum_id ); 
  1366.  
  1367. // Can't update what isn't there 
  1368. if ( !empty( $forum_id ) ) { 
  1369.  
  1370. // Get topics of forum 
  1371. if ( empty( $topic_count ) ) { 
  1372. $post_status = "'" . implode( "', '", array( bbp_get_trash_status_id(), bbp_get_spam_status_id() ) ) . "'"; 
  1373. $topic_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_parent = %d AND post_status IN ( {$post_status} ) AND post_type = '%s';", $forum_id, bbp_get_topic_post_type() ) ); 
  1374.  
  1375. // Update the count 
  1376. update_post_meta( $forum_id, '_bbp_topic_count_hidden', (int) $topic_count ); 
  1377.  
  1378. return (int) apply_filters( 'bbp_update_forum_topic_count_hidden', (int) $topic_count, $forum_id ); 
  1379.  
  1380. /** 
  1381. * Adjust the total reply count of a forum 
  1382. * 
  1383. * @since bbPress (r2464) 
  1384. * 
  1385. * @param int $forum_id Optional. Forum id or topic id. It is checked whether it 
  1386. * is a topic or a forum. If it's a topic, its parent,  
  1387. * i.e. the forum is automatically retrieved. 
  1388. * @param bool $total_count Optional. To return the total count or normal 
  1389. * count? 
  1390. * @uses bbp_get_forum_id() To get the forum id 
  1391. * @uses bbp_forum_query_subforum_ids() To get the subforum ids 
  1392. * @uses bbp_update_forum_reply_count() To update the forum reply count 
  1393. * @uses bbp_forum_query_topic_ids() To get the forum topic ids 
  1394. * @uses wpdb::prepare() To prepare the sql statement 
  1395. * @uses wpdb::get_var() To execute the query and get the var back 
  1396. * @uses update_post_meta() To update the forum's reply count meta 
  1397. * @uses apply_filters() Calls 'bbp_update_forum_topic_count' with the reply 
  1398. * count and forum id 
  1399. * @return int Forum reply count 
  1400. */ 
  1401. function bbp_update_forum_reply_count( $forum_id = 0 ) { 
  1402. global $wpdb; 
  1403.  
  1404. $forum_id = bbp_get_forum_id( $forum_id ); 
  1405. $children_reply_count = 0; 
  1406.  
  1407. // Loop through children and add together forum reply counts 
  1408. $children = bbp_forum_query_subforum_ids( $forum_id ); 
  1409. if ( !empty( $children ) ) { 
  1410. foreach ( (array) $children as $child ) { 
  1411. $children_reply_count += bbp_update_forum_reply_count( $child ); 
  1412.  
  1413. // Don't count replies if the forum is a category 
  1414. $topic_ids = bbp_forum_query_topic_ids( $forum_id ); 
  1415. if ( !empty( $topic_ids ) ) { 
  1416. $topic_ids = implode( ', ', wp_parse_id_list( $topic_ids ) ); 
  1417. $reply_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_parent IN ( {$topic_ids} ) AND post_status = '%s' AND post_type = '%s';", bbp_get_public_status_id(), bbp_get_reply_post_type() ) ); 
  1418. } else { 
  1419. $reply_count = 0; 
  1420.  
  1421. // Calculate total replies in this forum 
  1422. $total_replies = (int) $reply_count + $children_reply_count; 
  1423.  
  1424. // Update the count 
  1425. update_post_meta( $forum_id, '_bbp_reply_count', (int) $reply_count ); 
  1426. update_post_meta( $forum_id, '_bbp_total_reply_count', (int) $total_replies ); 
  1427.  
  1428. return (int) apply_filters( 'bbp_update_forum_reply_count', (int) $total_replies, $forum_id ); 
  1429.  
  1430. /** 
  1431. * Updates the counts of a forum. 
  1432. * 
  1433. * This calls a few internal functions that all run manual queries against the 
  1434. * database to get their results. As such, this function can be costly to run 
  1435. * but is necessary to keep everything accurate. 
  1436. * 
  1437. * @since bbPress (r2908) 
  1438. * 
  1439. * @param mixed $args Supports these arguments: 
  1440. * - forum_id: Forum id 
  1441. * - last_topic_id: Last topic id 
  1442. * - last_reply_id: Last reply id 
  1443. * - last_active_id: Last active post id 
  1444. * - last_active_time: last active time 
  1445. * @uses bbp_update_forum_last_topic_id() To update the forum last topic id 
  1446. * @uses bbp_update_forum_last_reply_id() To update the forum last reply id 
  1447. * @uses bbp_update_forum_last_active_id() To update the last active post id 
  1448. * @uses get_post_field() To get the post date of the last active id 
  1449. * @uses bbp_update_forum_last_active_time() To update the last active time 
  1450. * @uses bbp_update_forum_subforum_count() To update the subforum count 
  1451. * @uses bbp_update_forum_topic_count() To update the forum topic count 
  1452. * @uses bbp_update_forum_reply_count() To update the forum reply count 
  1453. * @uses bbp_update_forum_topic_count_hidden() To update the hidden topic count 
  1454. */ 
  1455. function bbp_update_forum( $args = '' ) { 
  1456.  
  1457. // Parse arguments against default values 
  1458. $r = bbp_parse_args( $args, array( 
  1459. 'forum_id' => 0,  
  1460. 'post_parent' => 0,  
  1461. 'last_topic_id' => 0,  
  1462. 'last_reply_id' => 0,  
  1463. 'last_active_id' => 0,  
  1464. 'last_active_time' => 0,  
  1465. 'last_active_status' => bbp_get_public_status_id() 
  1466. ), 'update_forum' ); 
  1467.  
  1468. // Last topic and reply ID's 
  1469. bbp_update_forum_last_topic_id( $r['forum_id'], $r['last_topic_id'] ); 
  1470. bbp_update_forum_last_reply_id( $r['forum_id'], $r['last_reply_id'] ); 
  1471.  
  1472. // Active dance 
  1473. $r['last_active_id'] = bbp_update_forum_last_active_id( $r['forum_id'], $r['last_active_id'] ); 
  1474.  
  1475. // If no active time was passed, get it from the last_active_id 
  1476. if ( empty( $r['last_active_time'] ) ) { 
  1477. $r['last_active_time'] = get_post_field( 'post_date', $r['last_active_id'] ); 
  1478.  
  1479. if ( bbp_get_public_status_id() === $r['last_active_status'] ) { 
  1480. bbp_update_forum_last_active_time( $r['forum_id'], $r['last_active_time'] ); 
  1481.  
  1482. // Counts 
  1483. bbp_update_forum_subforum_count ( $r['forum_id'] ); 
  1484. bbp_update_forum_reply_count ( $r['forum_id'] ); 
  1485. bbp_update_forum_topic_count ( $r['forum_id'] ); 
  1486. bbp_update_forum_topic_count_hidden( $r['forum_id'] ); 
  1487.  
  1488. // Update the parent forum if one was passed 
  1489. if ( !empty( $r['post_parent'] ) && is_numeric( $r['post_parent'] ) ) { 
  1490. bbp_update_forum( array( 
  1491. 'forum_id' => $r['post_parent'],  
  1492. 'post_parent' => get_post_field( 'post_parent', $r['post_parent'] ) 
  1493. ) ); 
  1494.  
  1495. /** Helpers *******************************************************************/ 
  1496.  
  1497. /** 
  1498. * Return an associative array of available topic statuses 
  1499. * 
  1500. * @since bbPress (r5059) 
  1501. * 
  1502. * @return array 
  1503. */ 
  1504. function bbp_get_forum_statuses() { 
  1505. return apply_filters( 'bbp_get_forum_statuses', array( 
  1506. 'open' => _x( 'Open', 'Open the forum', 'bbpress' ),  
  1507. 'closed' => _x( 'Closed', 'Close the forum', 'bbpress' ) 
  1508. ) ); 
  1509.  
  1510. /** 
  1511. * Return an associative array of forum types 
  1512. * 
  1513. * @since bbPress (r5059) 
  1514. * 
  1515. * @return array 
  1516. */ 
  1517. function bbp_get_forum_types() { 
  1518. return apply_filters( 'bbp_get_forum_types', array( 
  1519. 'forum' => _x( 'Forum', 'Forum accepts new topics', 'bbpress' ),  
  1520. 'category' => _x( 'Category', 'Forum is a category', 'bbpress' ) 
  1521. ) ); 
  1522.  
  1523. /** 
  1524. * Return an associative array of forum visibility 
  1525. * 
  1526. * @since bbPress (r5059) 
  1527. * 
  1528. * @return array 
  1529. */ 
  1530. function bbp_get_forum_visibilities() { 
  1531. return apply_filters( 'bbp_get_forum_visibilities', array( 
  1532. bbp_get_public_status_id() => _x( 'Public', 'Make forum public', 'bbpress' ),  
  1533. bbp_get_private_status_id() => _x( 'Private', 'Make forum private', 'bbpress' ),  
  1534. bbp_get_hidden_status_id() => _x( 'Hidden', 'Make forum hidden', 'bbpress' ) 
  1535. ) ); 
  1536.  
  1537. /** Queries *******************************************************************/ 
  1538.  
  1539. /** 
  1540. * Returns the hidden forum ids 
  1541. * 
  1542. * Only hidden forum ids are returned. Public and private ids are not. 
  1543. * 
  1544. * @since bbPress (r3007) 
  1545. * 
  1546. * @uses get_option() Returns the unserialized array of hidden forum ids 
  1547. * @uses apply_filters() Calls 'bbp_forum_query_topic_ids' with the topic ids 
  1548. * and forum id 
  1549. */ 
  1550. function bbp_get_hidden_forum_ids() { 
  1551. $forum_ids = get_option( '_bbp_hidden_forums', array() ); 
  1552.  
  1553. return apply_filters( 'bbp_get_hidden_forum_ids', (array) $forum_ids ); 
  1554.  
  1555. /** 
  1556. * Returns the private forum ids 
  1557. * 
  1558. * Only private forum ids are returned. Public and hidden ids are not. 
  1559. * 
  1560. * @since bbPress (r3007) 
  1561. * 
  1562. * @uses get_option() Returns the unserialized array of private forum ids 
  1563. * @uses apply_filters() Calls 'bbp_forum_query_topic_ids' with the topic ids 
  1564. * and forum id 
  1565. */ 
  1566. function bbp_get_private_forum_ids() { 
  1567. $forum_ids = get_option( '_bbp_private_forums', array() ); 
  1568.  
  1569. return apply_filters( 'bbp_get_private_forum_ids', (array) $forum_ids ); 
  1570.  
  1571. /** 
  1572. * Returns a meta_query that either includes or excludes hidden forum IDs 
  1573. * from a query. 
  1574. * 
  1575. * @since bbPress (r3291) 
  1576. * 
  1577. * @param string Optional. The type of value to return. (string|array|meta_query) 
  1578. * 
  1579. * @uses bbp_is_user_keymaster() 
  1580. * @uses bbp_get_hidden_forum_ids() 
  1581. * @uses bbp_get_private_forum_ids() 
  1582. * @uses apply_filters() 
  1583. */ 
  1584. function bbp_exclude_forum_ids( $type = 'string' ) { 
  1585.  
  1586. // Setup arrays 
  1587. $private = $hidden = $meta_query = $forum_ids = array(); 
  1588.  
  1589. // Default return value 
  1590. switch ( $type ) { 
  1591. case 'string' : 
  1592. $retval = ''; 
  1593. break; 
  1594.  
  1595. case 'array' : 
  1596. $retval = array(); 
  1597. break; 
  1598.  
  1599. case 'meta_query' : 
  1600. $retval = array( array() ) ; 
  1601. break; 
  1602.  
  1603. // Exclude for everyone but keymasters 
  1604. if ( ! bbp_is_user_keymaster() ) { 
  1605.  
  1606. // Private forums 
  1607. if ( !current_user_can( 'read_private_forums' ) ) 
  1608. $private = bbp_get_private_forum_ids(); 
  1609.  
  1610. // Hidden forums 
  1611. if ( !current_user_can( 'read_hidden_forums' ) ) 
  1612. $hidden = bbp_get_hidden_forum_ids(); 
  1613.  
  1614. // Merge private and hidden forums together 
  1615. $forum_ids = (array) array_filter( wp_parse_id_list( array_merge( $private, $hidden ) ) ); 
  1616.  
  1617. // There are forums that need to be excluded 
  1618. if ( !empty( $forum_ids ) ) { 
  1619.  
  1620. switch ( $type ) { 
  1621.  
  1622. // Separate forum ID's into a comma separated string 
  1623. case 'string' : 
  1624. $retval = implode( ', ', $forum_ids ); 
  1625. break; 
  1626.  
  1627. // Use forum_ids array 
  1628. case 'array' : 
  1629. $retval = $forum_ids; 
  1630. break; 
  1631.  
  1632. // Build a meta_query 
  1633. case 'meta_query' : 
  1634. $retval = array( 
  1635. 'key' => '_bbp_forum_id',  
  1636. 'value' => implode( ', ', $forum_ids ),  
  1637. 'type' => 'numeric',  
  1638. 'compare' => ( 1 < count( $forum_ids ) ) ? 'NOT IN' : '!=' 
  1639. ); 
  1640. break; 
  1641.  
  1642. // Filter and return the results 
  1643. return apply_filters( 'bbp_exclude_forum_ids', $retval, $forum_ids, $type ); 
  1644.  
  1645. /** 
  1646. * Adjusts forum, topic, and reply queries to exclude items that might be 
  1647. * contained inside hidden or private forums that the user does not have the 
  1648. * capability to view. 
  1649. * 
  1650. * Doing it with an action allows us to trap all WP_Query's rather than needing 
  1651. * to hardcode this logic into each query. It also protects forum content for 
  1652. * plugins that might be doing their own queries. 
  1653. * 
  1654. * @since bbPress (r3291) 
  1655. * 
  1656. * @param WP_Query $posts_query 
  1657. * 
  1658. * @uses apply_filters() 
  1659. * @uses bbp_exclude_forum_ids() 
  1660. * @uses bbp_get_topic_post_type() 
  1661. * @uses bbp_get_reply_post_type() 
  1662. * @return WP_Query 
  1663. */ 
  1664. function bbp_pre_get_posts_normalize_forum_visibility( $posts_query = null ) { 
  1665.  
  1666. // Bail if all forums are explicitly allowed 
  1667. if ( true === apply_filters( 'bbp_include_all_forums', false, $posts_query ) ) { 
  1668. return; 
  1669.  
  1670. // Bail if $posts_query is not an object or of incorrect class 
  1671. if ( !is_object( $posts_query ) || !is_a( $posts_query, 'WP_Query' ) ) { 
  1672. return; 
  1673.  
  1674. // Get query post types array . 
  1675. $post_types = (array) $posts_query->get( 'post_type' ); 
  1676.  
  1677. // Forum
  1678. if ( bbp_get_forum_post_type() === implode( '', $post_types ) ) { 
  1679.  
  1680. // Prevent accidental wp-admin post_row override 
  1681. if ( is_admin() && isset( $_REQUEST['post_status'] ) ) { 
  1682. return; 
  1683.  
  1684. /** Default ***********************************************************/ 
  1685.  
  1686. // Get any existing post status 
  1687. $post_stati = $posts_query->get( 'post_status' ); 
  1688.  
  1689. // Default to public status 
  1690. if ( empty( $post_stati ) ) { 
  1691. $post_stati[] = bbp_get_public_status_id(); 
  1692.  
  1693. // Split the status string 
  1694. } elseif ( is_string( $post_stati ) ) { 
  1695. $post_stati = explode( ', ', $post_stati ); 
  1696.  
  1697. /** Private ***********************************************************/ 
  1698.  
  1699. // Remove bbp_get_private_status_id() if user is not capable 
  1700. if ( ! current_user_can( 'read_private_forums' ) ) { 
  1701. $key = array_search( bbp_get_private_status_id(), $post_stati ); 
  1702. if ( !empty( $key ) ) { 
  1703. unset( $post_stati[$key] ); 
  1704.  
  1705. // ...or add it if they are 
  1706. } else { 
  1707. $post_stati[] = bbp_get_private_status_id(); 
  1708.  
  1709. /** Hidden ************************************************************/ 
  1710.  
  1711. // Remove bbp_get_hidden_status_id() if user is not capable 
  1712. if ( ! current_user_can( 'read_hidden_forums' ) ) { 
  1713. $key = array_search( bbp_get_hidden_status_id(), $post_stati ); 
  1714. if ( !empty( $key ) ) { 
  1715. unset( $post_stati[$key] ); 
  1716.  
  1717. // ...or add it if they are 
  1718. } else { 
  1719. $post_stati[] = bbp_get_hidden_status_id(); 
  1720.  
  1721. // Add the statuses 
  1722. $posts_query->set( 'post_status', array_unique( array_filter( $post_stati ) ) ); 
  1723.  
  1724. // Topics Or Replies 
  1725. if ( array_intersect( array( bbp_get_topic_post_type(), bbp_get_reply_post_type() ), $post_types ) ) { 
  1726.  
  1727. // Get forums to exclude 
  1728. $forum_ids = bbp_exclude_forum_ids( 'meta_query' ); 
  1729.  
  1730. // Bail if no forums to exclude 
  1731. if ( ! array_filter( $forum_ids ) ) { 
  1732. return; 
  1733.  
  1734. // Get any existing meta queries 
  1735. $meta_query = $posts_query->get( 'meta_query' ); 
  1736.  
  1737. // Add our meta query to existing 
  1738. $meta_query[] = $forum_ids; 
  1739.  
  1740. // Set the meta_query var 
  1741. $posts_query->set( 'meta_query', $meta_query ); 
  1742.  
  1743. /** 
  1744. * Returns the forum's topic ids 
  1745. * 
  1746. * Only topics with published and closed statuses are returned 
  1747. * 
  1748. * @since bbPress (r2908) 
  1749. * 
  1750. * @param int $forum_id Forum id 
  1751. * @uses bbp_get_topic_post_type() To get the topic post type 
  1752. * @uses bbp_get_public_child_ids() To get the topic ids 
  1753. * @uses apply_filters() Calls 'bbp_forum_query_topic_ids' with the topic ids 
  1754. * and forum id 
  1755. */ 
  1756. function bbp_forum_query_topic_ids( $forum_id ) { 
  1757. $topic_ids = bbp_get_public_child_ids( $forum_id, bbp_get_topic_post_type() ); 
  1758.  
  1759. return apply_filters( 'bbp_forum_query_topic_ids', $topic_ids, $forum_id ); 
  1760.  
  1761. /** 
  1762. * Returns the forum's subforum ids 
  1763. * 
  1764. * Only forums with published status are returned 
  1765. * 
  1766. * @since bbPress (r2908) 
  1767. * 
  1768. * @param int $forum_id Forum id 
  1769. * @uses bbp_get_forum_post_type() To get the forum post type 
  1770. * @uses bbp_get_public_child_ids() To get the forum ids 
  1771. * @uses apply_filters() Calls 'bbp_forum_query_subforum_ids' with the subforum 
  1772. * ids and forum id 
  1773. */ 
  1774. function bbp_forum_query_subforum_ids( $forum_id ) { 
  1775. $subforum_ids = bbp_get_all_child_ids( $forum_id, bbp_get_forum_post_type() ); 
  1776. //usort( $subforum_ids, '_bbp_forum_query_usort_subforum_ids' ); 
  1777.  
  1778. return apply_filters( 'bbp_get_forum_subforum_ids', $subforum_ids, $forum_id ); 
  1779.  
  1780. /** 
  1781. * Callback to sort forum ID's based on last active time 
  1782. * 
  1783. * @since bbPress (r3789) 
  1784. * @param int $a First forum ID to compare 
  1785. * @param int $b Second forum ID to compare 
  1786. * @return Position change based on sort 
  1787. */ 
  1788. function _bbp_forum_query_usort_subforum_ids( $a = 0, $b = 0 ) { 
  1789. $ta = get_post_meta( $a, '_bbp_last_active_time', true ); 
  1790. $tb = get_post_meta( $b, '_bbp_last_active_time', true ); 
  1791. return ( $ta < $tb ) ? -1 : 1; 
  1792.  
  1793. /** 
  1794. * Returns the forum's last reply id 
  1795. * 
  1796. * @since bbPress (r2908) 
  1797. * 
  1798. * @param int $forum_id Forum id 
  1799. * @param int $topic_ids Optional. Topic ids 
  1800. * @uses wp_cache_get() To check for cache and retrieve it 
  1801. * @uses bbp_forum_query_topic_ids() To get the forum's topic ids 
  1802. * @uses wpdb::prepare() To prepare the query 
  1803. * @uses wpdb::get_var() To execute the query and get the var back 
  1804. * @uses bbp_get_reply_post_type() To get the reply post type 
  1805. * @uses wp_cache_set() To set the cache for future use 
  1806. * @uses apply_filters() Calls 'bbp_forum_query_last_reply_id' with the reply id 
  1807. * and forum id 
  1808. */ 
  1809. function bbp_forum_query_last_reply_id( $forum_id, $topic_ids = 0 ) { 
  1810. global $wpdb; 
  1811.  
  1812. $cache_id = 'bbp_get_forum_' . $forum_id . '_reply_id'; 
  1813. $reply_id = wp_cache_get( $cache_id, 'bbpress_posts' ); 
  1814.  
  1815. if ( false === $reply_id ) { 
  1816.  
  1817. if ( empty( $topic_ids ) ) { 
  1818. $topic_ids = bbp_forum_query_topic_ids( $forum_id ); 
  1819.  
  1820. if ( !empty( $topic_ids ) ) { 
  1821. $topic_ids = implode( ', ', wp_parse_id_list( $topic_ids ) ); 
  1822. $reply_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_parent IN ( {$topic_ids} ) AND post_status = '%s' AND post_type = '%s' ORDER BY ID DESC LIMIT 1;", bbp_get_public_status_id(), bbp_get_reply_post_type() ) ); 
  1823. wp_cache_set( $cache_id, $reply_id, 'bbpress_posts' ); // May be (int) 0 
  1824. } else { 
  1825. wp_cache_set( $cache_id, '0', 'bbpress_posts' ); 
  1826.  
  1827. return (int) apply_filters( 'bbp_get_forum_last_reply_id', (int) $reply_id, $forum_id ); 
  1828.  
  1829. /** Listeners *****************************************************************/ 
  1830.  
  1831. /** 
  1832. * Check if it's a hidden forum or a topic or reply of a hidden forum and if 
  1833. * the user can't view it, then sets a 404 
  1834. * 
  1835. * @since bbPress (r2996) 
  1836. * 
  1837. * @uses current_user_can() To check if the current user can read private forums 
  1838. * @uses is_singular() To check if it's a singular page 
  1839. * @uses bbp_is_user_keymaster() To check if user is a keymaster 
  1840. * @uses bbp_get_forum_post_type() To get the forum post type 
  1841. * @uses bbp_get_topic_post_type() To get the topic post type 
  1842. * @uses bbp_get_reply_post_type() TO get the reply post type 
  1843. * @uses bbp_get_topic_forum_id() To get the topic forum id 
  1844. * @uses bbp_get_reply_forum_id() To get the reply forum id 
  1845. * @uses bbp_is_forum_hidden() To check if the forum is hidden or not 
  1846. * @uses bbp_set_404() To set a 404 status 
  1847. */ 
  1848. function bbp_forum_enforce_hidden() { 
  1849.  
  1850. // Bail if not viewing a single item or if user has caps 
  1851. if ( !is_singular() || bbp_is_user_keymaster() || current_user_can( 'read_hidden_forums' ) ) 
  1852. return; 
  1853.  
  1854. global $wp_query; 
  1855.  
  1856. // Define local variable 
  1857. $forum_id = 0; 
  1858.  
  1859. // Check post type 
  1860. switch ( $wp_query->get( 'post_type' ) ) { 
  1861.  
  1862. // Forum 
  1863. case bbp_get_forum_post_type() : 
  1864. $forum_id = bbp_get_forum_id( $wp_query->post->ID ); 
  1865. break; 
  1866.  
  1867. // Topic 
  1868. case bbp_get_topic_post_type() : 
  1869. $forum_id = bbp_get_topic_forum_id( $wp_query->post->ID ); 
  1870. break; 
  1871.  
  1872. // Reply 
  1873. case bbp_get_reply_post_type() : 
  1874. $forum_id = bbp_get_reply_forum_id( $wp_query->post->ID ); 
  1875. break; 
  1876.  
  1877.  
  1878. // If forum is explicitly hidden and user not capable, set 404 
  1879. if ( !empty( $forum_id ) && bbp_is_forum_hidden( $forum_id ) && !current_user_can( 'read_hidden_forums' ) ) 
  1880. bbp_set_404(); 
  1881.  
  1882. /** 
  1883. * Check if it's a private forum or a topic or reply of a private forum and if 
  1884. * the user can't view it, then sets a 404 
  1885. * 
  1886. * @since bbPress (r2996) 
  1887. * 
  1888. * @uses current_user_can() To check if the current user can read private forums 
  1889. * @uses is_singular() To check if it's a singular page 
  1890. * @uses bbp_is_user_keymaster() To check if user is a keymaster 
  1891. * @uses bbp_get_forum_post_type() To get the forum post type 
  1892. * @uses bbp_get_topic_post_type() To get the topic post type 
  1893. * @uses bbp_get_reply_post_type() TO get the reply post type 
  1894. * @uses bbp_get_topic_forum_id() To get the topic forum id 
  1895. * @uses bbp_get_reply_forum_id() To get the reply forum id 
  1896. * @uses bbp_is_forum_private() To check if the forum is private or not 
  1897. * @uses bbp_set_404() To set a 404 status 
  1898. */ 
  1899. function bbp_forum_enforce_private() { 
  1900.  
  1901. // Bail if not viewing a single item or if user has caps 
  1902. if ( !is_singular() || bbp_is_user_keymaster() || current_user_can( 'read_private_forums' ) ) 
  1903. return; 
  1904.  
  1905. global $wp_query; 
  1906.  
  1907. // Define local variable 
  1908. $forum_id = 0; 
  1909.  
  1910. // Check post type 
  1911. switch ( $wp_query->get( 'post_type' ) ) { 
  1912.  
  1913. // Forum 
  1914. case bbp_get_forum_post_type() : 
  1915. $forum_id = bbp_get_forum_id( $wp_query->post->ID ); 
  1916. break; 
  1917.  
  1918. // Topic 
  1919. case bbp_get_topic_post_type() : 
  1920. $forum_id = bbp_get_topic_forum_id( $wp_query->post->ID ); 
  1921. break; 
  1922.  
  1923. // Reply 
  1924. case bbp_get_reply_post_type() : 
  1925. $forum_id = bbp_get_reply_forum_id( $wp_query->post->ID ); 
  1926. break; 
  1927.  
  1928.  
  1929. // If forum is explicitly hidden and user not capable, set 404 
  1930. if ( !empty( $forum_id ) && bbp_is_forum_private( $forum_id ) && !current_user_can( 'read_private_forums' ) ) 
  1931. bbp_set_404(); 
  1932.  
  1933. /** Permissions ***************************************************************/ 
  1934.  
  1935. /** 
  1936. * Redirect if unathorized user is attempting to edit a forum 
  1937. * 
  1938. * @since bbPress (r3607) 
  1939. * 
  1940. * @uses bbp_is_forum_edit() 
  1941. * @uses current_user_can() 
  1942. * @uses bbp_get_forum_id() 
  1943. * @uses wp_safe_redirect() 
  1944. * @uses bbp_get_forum_permalink() 
  1945. */ 
  1946. function bbp_check_forum_edit() { 
  1947.  
  1948. // Bail if not editing a topic 
  1949. if ( !bbp_is_forum_edit() ) 
  1950. return; 
  1951.  
  1952. // User cannot edit topic, so redirect back to reply 
  1953. if ( !current_user_can( 'edit_forum', bbp_get_forum_id() ) ) { 
  1954. wp_safe_redirect( bbp_get_forum_permalink() ); 
  1955. exit(); 
  1956.  
  1957. /** 
  1958. * Delete all topics (and their replies) for a specific forum ID 
  1959. * 
  1960. * @since bbPress (r3668) 
  1961. * 
  1962. * @param int $forum_id 
  1963. * @uses bbp_get_forum_id() To validate the forum ID 
  1964. * @uses bbp_is_forum() To make sure it's a forum 
  1965. * @uses bbp_get_topic_post_type() To get the topic post type 
  1966. * @uses bbp_topics() To make sure there are topics to loop through 
  1967. * @uses wp_trash_post() To trash the post 
  1968. * @uses update_post_meta() To update the forum meta of trashed topics 
  1969. * @return If forum is not valid 
  1970. */ 
  1971. function bbp_delete_forum_topics( $forum_id = 0 ) { 
  1972.  
  1973. // Validate forum ID 
  1974. $forum_id = bbp_get_forum_id( $forum_id ); 
  1975. if ( empty( $forum_id ) ) 
  1976. return; 
  1977.  
  1978. // Forum is being permanently deleted, so its content has go too 
  1979. // Note that we get all post statuses here 
  1980. $topics = new WP_Query( array( 
  1981. 'suppress_filters' => true,  
  1982. 'post_type' => bbp_get_topic_post_type(),  
  1983. 'post_parent' => $forum_id,  
  1984. 'post_status' => array_keys( get_post_stati() ),  
  1985. 'posts_per_page' => -1,  
  1986. 'nopaging' => true,  
  1987. 'fields' => 'id=>parent' 
  1988. ) ); 
  1989.  
  1990. // Loop through and delete child topics. Topic replies will get deleted by 
  1991. // the bbp_delete_topic() action. 
  1992. if ( !empty( $topics->posts ) ) { 
  1993. foreach ( $topics->posts as $topic ) { 
  1994. wp_delete_post( $topic->ID, true ); 
  1995.  
  1996. // Reset the $post global 
  1997. wp_reset_postdata(); 
  1998.  
  1999. // Cleanup 
  2000. unset( $topics ); 
  2001.  
  2002. /** 
  2003. * Trash all topics inside a forum 
  2004. * 
  2005. * @since bbPress (r3668) 
  2006. * 
  2007. * @param int $forum_id 
  2008. * @uses bbp_get_forum_id() To validate the forum ID 
  2009. * @uses bbp_is_forum() To make sure it's a forum 
  2010. * @uses bbp_get_public_status_id() To return public post status 
  2011. * @uses bbp_get_closed_status_id() To return closed post status 
  2012. * @uses bbp_get_pending_status_id() To return pending post status 
  2013. * @uses bbp_get_topic_post_type() To get the topic post type 
  2014. * @uses wp_trash_post() To trash the post 
  2015. * @uses update_post_meta() To update the forum meta of trashed topics 
  2016. * @return If forum is not valid 
  2017. */ 
  2018. function bbp_trash_forum_topics( $forum_id = 0 ) { 
  2019.  
  2020. // Validate forum ID 
  2021. $forum_id = bbp_get_forum_id( $forum_id ); 
  2022. if ( empty( $forum_id ) ) 
  2023. return; 
  2024.  
  2025. // Allowed post statuses to pre-trash 
  2026. $post_stati = implode( ', ', array( 
  2027. bbp_get_public_status_id(),  
  2028. bbp_get_closed_status_id(),  
  2029. bbp_get_pending_status_id() 
  2030. ) ); 
  2031.  
  2032. // Forum is being trashed, so its topics and replies are trashed too 
  2033. $topics = new WP_Query( array( 
  2034. 'suppress_filters' => true,  
  2035. 'post_type' => bbp_get_topic_post_type(),  
  2036. 'post_parent' => $forum_id,  
  2037. 'post_status' => $post_stati,  
  2038. 'posts_per_page' => -1,  
  2039. 'nopaging' => true,  
  2040. 'fields' => 'id=>parent' 
  2041. ) ); 
  2042.  
  2043. // Loop through and trash child topics. Topic replies will get trashed by 
  2044. // the bbp_trash_topic() action. 
  2045. if ( !empty( $topics->posts ) ) { 
  2046.  
  2047. // Prevent debug notices 
  2048. $pre_trashed_topics = array(); 
  2049.  
  2050. // Loop through topics, trash them, and add them to array 
  2051. foreach ( $topics->posts as $topic ) { 
  2052. wp_trash_post( $topic->ID, true ); 
  2053. $pre_trashed_topics[] = $topic->ID; 
  2054.  
  2055. // Set a post_meta entry of the topics that were trashed by this action. 
  2056. // This is so we can possibly untrash them, without untrashing topics 
  2057. // that were purposefully trashed before. 
  2058. update_post_meta( $forum_id, '_bbp_pre_trashed_topics', $pre_trashed_topics ); 
  2059.  
  2060. // Reset the $post global 
  2061. wp_reset_postdata(); 
  2062.  
  2063. // Cleanup 
  2064. unset( $topics ); 
  2065.  
  2066. /** 
  2067. * Trash all topics inside a forum 
  2068. * 
  2069. * @since bbPress (r3668) 
  2070. * 
  2071. * @param int $forum_id 
  2072. * @uses bbp_get_forum_id() To validate the forum ID 
  2073. * @uses bbp_is_forum() To make sure it's a forum 
  2074. * @uses get_post_meta() To update the forum meta of trashed topics 
  2075. * @uses wp_untrash_post() To trash the post 
  2076. * @return If forum is not valid 
  2077. */ 
  2078. function bbp_untrash_forum_topics( $forum_id = 0 ) { 
  2079.  
  2080. // Validate forum ID 
  2081. $forum_id = bbp_get_forum_id( $forum_id ); 
  2082.  
  2083. if ( empty( $forum_id ) ) 
  2084. return; 
  2085.  
  2086. // Get the topics that were not previously trashed 
  2087. $pre_trashed_topics = get_post_meta( $forum_id, '_bbp_pre_trashed_topics', true ); 
  2088.  
  2089. // There are topics to untrash 
  2090. if ( !empty( $pre_trashed_topics ) ) { 
  2091.  
  2092. // Maybe reverse the trashed topics array 
  2093. if ( is_array( $pre_trashed_topics ) ) 
  2094. $pre_trashed_topics = array_reverse( $pre_trashed_topics ); 
  2095.  
  2096. // Loop through topics 
  2097. foreach ( (array) $pre_trashed_topics as $topic ) { 
  2098. wp_untrash_post( $topic ); 
  2099.  
  2100. /** Before Delete/Trash/Untrash ***********************************************/ 
  2101.  
  2102. /** 
  2103. * Called before deleting a forum. 
  2104. * 
  2105. * This function is supplemental to the actual forum deletion which is 
  2106. * handled by WordPress core API functions. It is used to clean up after 
  2107. * a forum that is being deleted. 
  2108. * 
  2109. * @since bbPress (r3668) 
  2110. * @uses bbp_get_forum_id() To get the forum id 
  2111. * @uses bbp_is_forum() To check if the passed id is a forum 
  2112. * @uses do_action() Calls 'bbp_delete_forum' with the forum id 
  2113. */ 
  2114. function bbp_delete_forum( $forum_id = 0 ) { 
  2115. $forum_id = bbp_get_forum_id( $forum_id ); 
  2116.  
  2117. if ( empty( $forum_id ) || !bbp_is_forum( $forum_id ) ) 
  2118. return false; 
  2119.  
  2120. do_action( 'bbp_delete_forum', $forum_id ); 
  2121.  
  2122. /** 
  2123. * Called before trashing a forum 
  2124. * 
  2125. * This function is supplemental to the actual forum being trashed which is 
  2126. * handled by WordPress core API functions. It is used to clean up after 
  2127. * a forum that is being trashed. 
  2128. * 
  2129. * @since bbPress (r3668) 
  2130. * @uses bbp_get_forum_id() To get the forum id 
  2131. * @uses bbp_is_forum() To check if the passed id is a forum 
  2132. * @uses do_action() Calls 'bbp_trash_forum' with the forum id 
  2133. */ 
  2134. function bbp_trash_forum( $forum_id = 0 ) { 
  2135. $forum_id = bbp_get_forum_id( $forum_id ); 
  2136.  
  2137. if ( empty( $forum_id ) || !bbp_is_forum( $forum_id ) ) 
  2138. return false; 
  2139.  
  2140. do_action( 'bbp_trash_forum', $forum_id ); 
  2141.  
  2142. /** 
  2143. * Called before untrashing a forum 
  2144. * 
  2145. * @since bbPress (r3668) 
  2146. * @uses bbp_get_forum_id() To get the forum id 
  2147. * @uses bbp_is_forum() To check if the passed id is a forum 
  2148. * @uses do_action() Calls 'bbp_untrash_forum' with the forum id 
  2149. */ 
  2150. function bbp_untrash_forum( $forum_id = 0 ) { 
  2151. $forum_id = bbp_get_forum_id( $forum_id ); 
  2152.  
  2153. if ( empty( $forum_id ) || !bbp_is_forum( $forum_id ) ) 
  2154. return false; 
  2155.  
  2156. do_action( 'bbp_untrash_forum', $forum_id ); 
  2157.  
  2158. /** After Delete/Trash/Untrash ************************************************/ 
  2159.  
  2160. /** 
  2161. * Called after deleting a forum 
  2162. * 
  2163. * @since bbPress (r3668) 
  2164. * @uses bbp_get_forum_id() To get the forum id 
  2165. * @uses bbp_is_forum() To check if the passed id is a forum 
  2166. * @uses do_action() Calls 'bbp_deleted_forum' with the forum id 
  2167. */ 
  2168. function bbp_deleted_forum( $forum_id = 0 ) { 
  2169. $forum_id = bbp_get_forum_id( $forum_id ); 
  2170.  
  2171. if ( empty( $forum_id ) || !bbp_is_forum( $forum_id ) ) 
  2172. return false; 
  2173.  
  2174. do_action( 'bbp_deleted_forum', $forum_id ); 
  2175.  
  2176. /** 
  2177. * Called after trashing a forum 
  2178. * 
  2179. * @since bbPress (r3668) 
  2180. * @uses bbp_get_forum_id() To get the forum id 
  2181. * @uses bbp_is_forum() To check if the passed id is a forum 
  2182. * @uses do_action() Calls 'bbp_trashed_forum' with the forum id 
  2183. */ 
  2184. function bbp_trashed_forum( $forum_id = 0 ) { 
  2185. $forum_id = bbp_get_forum_id( $forum_id ); 
  2186.  
  2187. if ( empty( $forum_id ) || !bbp_is_forum( $forum_id ) ) 
  2188. return false; 
  2189.  
  2190. do_action( 'bbp_trashed_forum', $forum_id ); 
  2191.  
  2192. /** 
  2193. * Called after untrashing a forum 
  2194. * 
  2195. * @since bbPress (r3668) 
  2196. * @uses bbp_get_forum_id() To get the forum id 
  2197. * @uses bbp_is_forum() To check if the passed id is a forum 
  2198. * @uses do_action() Calls 'bbp_untrashed_forum' with the forum id 
  2199. */ 
  2200. function bbp_untrashed_forum( $forum_id = 0 ) { 
  2201. $forum_id = bbp_get_forum_id( $forum_id ); 
  2202.  
  2203. if ( empty( $forum_id ) || !bbp_is_forum( $forum_id ) ) 
  2204. return false; 
  2205.  
  2206. do_action( 'bbp_untrashed_forum', $forum_id ); 
.