[ Index ]

PHP Cross Reference of BBPress

title

Body

[close]

/src/includes/forums/ -> functions.php (source)

   1  <?php
   2  
   3  /**
   4   * bbPress Forum Functions
   5   *
   6   * @package bbPress
   7   * @subpackage Functions
   8   */
   9  
  10  // Exit if accessed directly
  11  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 2.0.0 bbPress (r3349)
  20   *
  21   * @param array $forum_data Forum post data
  22   * @param array $forum_meta Forum meta data
  23   */
  24  function bbp_insert_forum( $forum_data = array(), $forum_meta = array() ) {
  25  
  26      // Forum
  27      $forum_data = bbp_parse_args( $forum_data, array(
  28          'post_parent'    => 0, // forum ID
  29          'post_status'    => bbp_get_public_status_id(),
  30          'post_type'      => bbp_get_forum_post_type(),
  31          'post_author'    => bbp_get_current_user_id(),
  32          'post_password'  => '',
  33          'post_content'   => '',
  34          'post_title'     => '',
  35          'menu_order'     => 0,
  36          'comment_status' => 'closed'
  37      ), 'insert_forum' );
  38  
  39      // Insert forum
  40      $forum_id = wp_insert_post( $forum_data, false );
  41  
  42      // Bail if no forum was added
  43      if ( empty( $forum_id ) ) {
  44          return false;
  45      }
  46  
  47      // Forum meta
  48      $forum_meta = bbp_parse_args( $forum_meta, array(
  49          'forum_type'           => 'forum',
  50          'status'               => 'open',
  51          'reply_count'          => 0,
  52          'topic_count'          => 0,
  53          'topic_count_hidden'   => 0,
  54          'total_reply_count'    => 0,
  55          'total_topic_count'    => 0,
  56          'last_topic_id'        => 0,
  57          'last_reply_id'        => 0,
  58          'last_active_id'       => 0,
  59          'last_active_time'     => 0,
  60          'forum_subforum_count' => 0,
  61      ), 'insert_forum_meta' );
  62  
  63      // Insert forum meta
  64      foreach ( $forum_meta as $meta_key => $meta_value ) {
  65  
  66          // Prefix if not prefixed
  67          if ( '_bbp_' !== substr( $meta_key, 0, 5 ) ) {
  68              $meta_key = '_bbp_' . $meta_key;
  69          }
  70  
  71          // Update the meta
  72          update_post_meta( $forum_id, $meta_key, $meta_value );
  73      }
  74  
  75      // Update the forum and hierarchy
  76      bbp_update_forum( array(
  77          'forum_id'    => $forum_id,
  78          'post_parent' => $forum_data['post_parent']
  79      ) );
  80  
  81      // Maybe make private
  82      if ( bbp_is_forum_private( $forum_id, false ) ) {
  83          bbp_privatize_forum( $forum_id );
  84  
  85      // Maybe make hidden
  86      } elseif ( bbp_is_forum_hidden( $forum_id, false ) ) {
  87          bbp_hide_forum( $forum_id );
  88  
  89      // Publicize
  90      } else {
  91          bbp_publicize_forum( $forum_id );
  92      }
  93  
  94      /**
  95       * Fires after forum has been inserted via `bbp_insert_forum`.
  96       *
  97       * @since 2.6.0 bbPress (r6036)
  98       *
  99       * @param int $forum_id The forum id.
 100       */
 101      do_action( 'bbp_insert_forum', (int) $forum_id );
 102  
 103      // Bump the last changed cache
 104      wp_cache_set( 'last_changed', microtime(), 'bbpress_posts' );
 105  
 106      // Return forum_id
 107      return $forum_id;
 108  }
 109  
 110  /** Post Form Handlers ********************************************************/
 111  
 112  /**
 113   * Handles the front end forum submission
 114   *
 115   * @param string $action The requested action to compare this function to
 116   */
 117  function bbp_new_forum_handler( $action = '' ) {
 118  
 119      // Bail if action is not bbp-new-forum
 120      if ( 'bbp-new-forum' !== $action ) {
 121          return;
 122      }
 123  
 124      // Nonce check
 125      if ( ! bbp_verify_nonce_request( 'bbp-new-forum' ) ) {
 126          bbp_add_error( 'bbp_new_forum_nonce', __( '<strong>Error</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
 127          return;
 128      }
 129  
 130      // Define local variable(s)
 131      $view_all = false;
 132      $forum_parent_id = $forum_author = 0;
 133      $forum_title = $forum_content = '';
 134      $anonymous_data = array();
 135  
 136      /** Forum Author **********************************************************/
 137  
 138      // User cannot create forums
 139      if ( ! current_user_can( 'publish_forums' ) ) {
 140          bbp_add_error( 'bbp_forum_permission', __( '<strong>Error</strong>: You do not have permission to create new forums.', 'bbpress' ) );
 141          return;
 142      }
 143  
 144      // Forum author is current user
 145      $forum_author = bbp_get_current_user_id();
 146  
 147      // Remove kses filters from title and content for capable users and if the nonce is verified
 148      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'] ) {
 149          remove_filter( 'bbp_new_forum_pre_title',   'wp_filter_kses'      );
 150          remove_filter( 'bbp_new_forum_pre_content', 'bbp_encode_bad',  10 );
 151          remove_filter( 'bbp_new_forum_pre_content', 'bbp_filter_kses', 30 );
 152      }
 153  
 154      /** Forum Title ***********************************************************/
 155  
 156      if ( ! empty( $_POST['bbp_forum_title'] ) ) {
 157          $forum_title = sanitize_text_field( $_POST['bbp_forum_title'] );
 158      }
 159  
 160      // Filter and sanitize
 161      $forum_title = apply_filters( 'bbp_new_forum_pre_title', $forum_title );
 162  
 163      // No forum title
 164      if ( empty( $forum_title ) ) {
 165          bbp_add_error( 'bbp_forum_title', __( '<strong>Error</strong>: Your forum needs a title.', 'bbpress' ) );
 166      }
 167  
 168      // Title too long
 169      if ( bbp_is_title_too_long( $forum_title ) ) {
 170          bbp_add_error( 'bbp_forum_title', __( '<strong>Error</strong>: Your title is too long.', 'bbpress' ) );
 171      }
 172  
 173      /** Forum Content *********************************************************/
 174  
 175      if ( ! empty( $_POST['bbp_forum_content'] ) ) {
 176          $forum_content = $_POST['bbp_forum_content'];
 177      }
 178  
 179      // Filter and sanitize
 180      $forum_content = apply_filters( 'bbp_new_forum_pre_content', $forum_content );
 181  
 182      // No forum content
 183      if ( empty( $forum_content ) ) {
 184          bbp_add_error( 'bbp_forum_content', __( '<strong>Error</strong>: Your forum description cannot be empty.', 'bbpress' ) );
 185      }
 186  
 187      /** Forum Parent **********************************************************/
 188  
 189      // Forum parent was passed (the norm)
 190      if ( ! empty( $_POST['bbp_forum_parent_id'] ) ) {
 191          $forum_parent_id = bbp_get_forum_id( $_POST['bbp_forum_parent_id'] );
 192      }
 193  
 194      // Filter and sanitize
 195      $forum_parent_id = apply_filters( 'bbp_new_forum_pre_parent_id', $forum_parent_id );
 196  
 197      // No forum parent was passed (should never happen)
 198      if ( empty( $forum_parent_id ) ) {
 199          bbp_add_error( 'bbp_new_forum_missing_parent', __( '<strong>Error</strong>: Your forum must have a parent.', 'bbpress' ) );
 200  
 201      // Forum exists
 202      } elseif ( ! empty( $forum_parent_id ) ) {
 203  
 204          // Forum is a category
 205          if ( bbp_is_forum_category( $forum_parent_id ) ) {
 206              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' ) );
 207          }
 208  
 209          // Forum is closed and user cannot access
 210          if ( bbp_is_forum_closed( $forum_parent_id ) && ! current_user_can( 'edit_forum', $forum_parent_id ) ) {
 211              bbp_add_error( 'bbp_new_forum_forum_closed', __( '<strong>Error</strong>: This forum has been closed to new forums.', 'bbpress' ) );
 212          }
 213  
 214          // Forum is private and user cannot access
 215          if ( bbp_is_forum_private( $forum_parent_id ) && ! current_user_can( 'read_forum', $forum_parent_id ) ) {
 216              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' ) );
 217          }
 218  
 219          // Forum is hidden and user cannot access
 220          if ( bbp_is_forum_hidden( $forum_parent_id ) && ! current_user_can( 'read_forum', $forum_parent_id ) ) {
 221              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' ) );
 222          }
 223      }
 224  
 225      /** Forum Flooding ********************************************************/
 226  
 227      if ( ! bbp_check_for_flood( $anonymous_data, $forum_author ) ) {
 228          bbp_add_error( 'bbp_forum_flood', __( '<strong>Error</strong>: Slow down; you move too fast.', 'bbpress' ) );
 229      }
 230  
 231      /** Forum Duplicate *******************************************************/
 232  
 233      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 ) ) ) {
 234          bbp_add_error( 'bbp_forum_duplicate', __( '<strong>Error</strong>: This forum already exists.', 'bbpress' ) );
 235      }
 236  
 237      /** Forum Bad Words *******************************************************/
 238  
 239      if ( ! bbp_check_for_moderation( $anonymous_data, $forum_author, $forum_title, $forum_content, true ) ) {
 240          bbp_add_error( 'bbp_forum_moderation', __( '<strong>Error</strong>: Your forum cannot be created at this time.', 'bbpress' ) );
 241      }
 242  
 243      /** Forum Moderation ******************************************************/
 244  
 245      // Default to published
 246      $forum_status = bbp_get_public_status_id();
 247  
 248      // Maybe force into pending
 249      if ( ! bbp_check_for_moderation( $anonymous_data, $forum_author, $forum_title, $forum_content ) ) {
 250          $forum_status = bbp_get_pending_status_id();
 251      }
 252  
 253      /** Additional Actions (Before Save) **************************************/
 254  
 255      do_action( 'bbp_new_forum_pre_extras', $forum_parent_id );
 256  
 257      // Bail if errors
 258      if ( bbp_has_errors() ) {
 259          return;
 260      }
 261  
 262      /** No Errors *************************************************************/
 263  
 264      // Add the content of the form to $forum_data as an array
 265      // Just in time manipulation of forum data before being created
 266      $forum_data = apply_filters( 'bbp_new_forum_pre_insert', array(
 267          'post_author'    => $forum_author,
 268          'post_title'     => $forum_title,
 269          'post_content'   => $forum_content,
 270          'post_parent'    => $forum_parent_id,
 271          'post_status'    => $forum_status,
 272          'post_type'      => bbp_get_forum_post_type(),
 273          'comment_status' => 'closed'
 274      ) );
 275  
 276      // Insert forum
 277      $forum_id = wp_insert_post( $forum_data, true );
 278  
 279      /** No Errors *************************************************************/
 280  
 281      if ( ! empty( $forum_id ) && ! is_wp_error( $forum_id ) ) {
 282  
 283          /** Trash Check *******************************************************/
 284  
 285          // If the forum is trash, or the forum_status is switched to
 286          // trash, trash it properly
 287          if ( ( get_post_field( 'post_status', $forum_id ) === bbp_get_trash_status_id() ) || ( $forum_data['post_status'] === bbp_get_trash_status_id() ) ) {
 288  
 289              // Trash the reply
 290              wp_trash_post( $forum_id );
 291  
 292              // Force view=all
 293              $view_all = true;
 294          }
 295  
 296          /** Spam Check ********************************************************/
 297  
 298          // If reply or forum are spam, officially spam this reply
 299          if ( $forum_data['post_status'] === bbp_get_spam_status_id() ) {
 300              add_post_meta( $forum_id, '_bbp_spam_meta_status', bbp_get_public_status_id() );
 301  
 302              // Force view=all
 303              $view_all = true;
 304          }
 305  
 306          /** Update counts, etc... *********************************************/
 307  
 308          do_action( 'bbp_new_forum', array(
 309              'forum_id'           => $forum_id,
 310              'post_parent'        => $forum_parent_id,
 311              'forum_author'       => $forum_author,
 312              'last_topic_id'      => 0,
 313              'last_reply_id'      => 0,
 314              'last_active_id'     => 0,
 315              'last_active_time'   => 0,
 316              'last_active_status' => bbp_get_public_status_id()
 317          ) );
 318  
 319          /** Additional Actions (After Save) ***********************************/
 320  
 321          do_action( 'bbp_new_forum_post_extras', $forum_id );
 322  
 323          /** Redirect **********************************************************/
 324  
 325          // Redirect to
 326          $redirect_to  = bbp_get_redirect_to();
 327  
 328          // Get the forum URL
 329          $redirect_url = bbp_get_forum_permalink( $forum_id, $redirect_to );
 330  
 331          // Add view all?
 332          if ( bbp_get_view_all() || ! empty( $view_all ) ) {
 333  
 334              // User can moderate, so redirect to forum with view all set
 335              if ( current_user_can( 'moderate', $forum_id ) ) {
 336                  $redirect_url = bbp_add_view_all( $redirect_url );
 337  
 338              // User cannot moderate, so redirect to forum
 339              } else {
 340                  $redirect_url = bbp_get_forum_permalink( $forum_id );
 341              }
 342          }
 343  
 344          // Allow to be filtered
 345          $redirect_url = apply_filters( 'bbp_new_forum_redirect_to', $redirect_url, $redirect_to );
 346  
 347          /** Successful Save ***************************************************/
 348  
 349          // Redirect back to new forum
 350          bbp_redirect( $redirect_url );
 351  
 352      /** Errors ****************************************************************/
 353  
 354      // WP_Error
 355      } elseif ( is_wp_error( $forum_id ) ) {
 356          bbp_add_error( 'bbp_forum_error', sprintf( __( '<strong>Error</strong>: The following problem(s) occurred: %s', 'bbpress' ), $forum_id->get_error_message() ) );
 357  
 358      // Generic error
 359      } else {
 360          bbp_add_error( 'bbp_forum_error', __( '<strong>Error</strong>: The forum was not created.', 'bbpress' ) );
 361      }
 362  }
 363  
 364  /**
 365   * Handles the front end edit forum submission
 366   *
 367   * @param string $action The requested action to compare this function to
 368   */
 369  function bbp_edit_forum_handler( $action = '' ) {
 370  
 371      // Bail if action is not bbp-edit-forum
 372      if ( 'bbp-edit-forum' !== $action ) {
 373          return;
 374      }
 375  
 376      // Define local variable(s)
 377      $anonymous_data = array();
 378      $forum = $forum_id = $forum_parent_id = 0;
 379      $forum_title = $forum_content = $forum_edit_reason = '';
 380  
 381      /** Forum *****************************************************************/
 382  
 383      // Forum id was not passed
 384      if ( empty( $_POST['bbp_forum_id'] ) ) {
 385          bbp_add_error( 'bbp_edit_forum_id', __( '<strong>Error</strong>: Forum ID not found.', 'bbpress' ) );
 386          return;
 387  
 388      // Forum id was passed
 389      } elseif ( is_numeric( $_POST['bbp_forum_id'] ) ) {
 390          $forum_id = (int) $_POST['bbp_forum_id'];
 391          $forum    = bbp_get_forum( $forum_id );
 392      }
 393  
 394      // Nonce check
 395      if ( ! bbp_verify_nonce_request( 'bbp-edit-forum_' . $forum_id ) ) {
 396          bbp_add_error( 'bbp_edit_forum_nonce', __( '<strong>Error</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
 397          return;
 398  
 399      // Forum does not exist
 400      } elseif ( empty( $forum ) ) {
 401          bbp_add_error( 'bbp_edit_forum_not_found', __( '<strong>Error</strong>: The forum you want to edit was not found.', 'bbpress' ) );
 402          return;
 403  
 404      // User cannot edit this forum
 405      } elseif ( ! current_user_can( 'edit_forum', $forum_id ) ) {
 406          bbp_add_error( 'bbp_edit_forum_permission', __( '<strong>Error</strong>: You do not have permission to edit that forum.', 'bbpress' ) );
 407          return;
 408      }
 409  
 410      // Remove kses filters from title and content for capable users and if the nonce is verified
 411      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'] ) ) {
 412          remove_filter( 'bbp_edit_forum_pre_title',   'wp_filter_kses'      );
 413          remove_filter( 'bbp_edit_forum_pre_content', 'bbp_encode_bad',  10 );
 414          remove_filter( 'bbp_edit_forum_pre_content', 'bbp_filter_kses', 30 );
 415      }
 416  
 417      /** Forum Parent ***********************************************************/
 418  
 419      // Forum parent id was passed
 420      if ( ! empty( $_POST['bbp_forum_parent_id'] ) ) {
 421          $forum_parent_id = bbp_get_forum_id( $_POST['bbp_forum_parent_id'] );
 422      }
 423  
 424      // Current forum this forum is in
 425      $current_parent_forum_id = bbp_get_forum_parent_id( $forum_id );
 426  
 427      // Forum exists
 428      if ( ! empty( $forum_parent_id ) && ( $forum_parent_id !== $current_parent_forum_id ) ) {
 429  
 430          // Forum is closed and user cannot access
 431          if ( bbp_is_forum_closed( $forum_parent_id ) && ! current_user_can( 'edit_forum', $forum_parent_id ) ) {
 432              bbp_add_error( 'bbp_edit_forum_forum_closed', __( '<strong>Error</strong>: This forum has been closed to new forums.', 'bbpress' ) );
 433          }
 434  
 435          // Forum is private and user cannot access
 436          if ( bbp_is_forum_private( $forum_parent_id ) && ! current_user_can( 'read_forum', $forum_parent_id ) ) {
 437              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' ) );
 438          }
 439  
 440          // Forum is hidden and user cannot access
 441          if ( bbp_is_forum_hidden( $forum_parent_id ) && ! current_user_can( 'read_forum', $forum_parent_id ) ) {
 442              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' ) );
 443          }
 444      }
 445  
 446      /** Forum Title ***********************************************************/
 447  
 448      if ( ! empty( $_POST['bbp_forum_title'] ) ) {
 449          $forum_title = sanitize_text_field( $_POST['bbp_forum_title'] );
 450      }
 451  
 452      // Filter and sanitize
 453      $forum_title = apply_filters( 'bbp_edit_forum_pre_title', $forum_title, $forum_id );
 454  
 455      // No forum title
 456      if ( empty( $forum_title ) ) {
 457          bbp_add_error( 'bbp_edit_forum_title', __( '<strong>Error</strong>: Your forum needs a title.', 'bbpress' ) );
 458      }
 459  
 460      // Title too long
 461      if ( bbp_is_title_too_long( $forum_title ) ) {
 462          bbp_add_error( 'bbp_forum_title', __( '<strong>Error</strong>: Your title is too long.', 'bbpress' ) );
 463      }
 464  
 465      /** Forum Content *********************************************************/
 466  
 467      if ( ! empty( $_POST['bbp_forum_content'] ) ) {
 468          $forum_content = $_POST['bbp_forum_content'];
 469      }
 470  
 471      // Filter and sanitize
 472      $forum_content = apply_filters( 'bbp_edit_forum_pre_content', $forum_content, $forum_id );
 473  
 474      // No forum content
 475      if ( empty( $forum_content ) ) {
 476          bbp_add_error( 'bbp_edit_forum_content', __( '<strong>Error</strong>: Your forum description cannot be empty.', 'bbpress' ) );
 477      }
 478  
 479      /** Forum Bad Words *******************************************************/
 480  
 481      if ( ! bbp_check_for_moderation( $anonymous_data, bbp_get_forum_author_id( $forum_id ), $forum_title, $forum_content, true ) ) {
 482          bbp_add_error( 'bbp_forum_moderation', __( '<strong>Error</strong>: Your forum cannot be edited at this time.', 'bbpress' ) );
 483      }
 484  
 485      /** Forum Moderation ******************************************************/
 486  
 487      // Use existing post_status
 488      $forum_status = $forum->post_status;
 489  
 490      // Maybe force into pending
 491      if ( ! bbp_check_for_moderation( $anonymous_data, bbp_get_forum_author_id( $forum_id ), $forum_title, $forum_content ) ) {
 492          $forum_status = bbp_get_pending_status_id();
 493      }
 494  
 495      /** Additional Actions (Before Save) **************************************/
 496  
 497      do_action( 'bbp_edit_forum_pre_extras', $forum_id );
 498  
 499      // Bail if errors
 500      if ( bbp_has_errors() ) {
 501          return;
 502      }
 503  
 504      /** No Errors *************************************************************/
 505  
 506      // Add the content of the form to $forum_data as an array
 507      // Just in time manipulation of forum data before being edited
 508      $forum_data = apply_filters( 'bbp_edit_forum_pre_insert', array(
 509          'ID'           => $forum_id,
 510          'post_title'   => $forum_title,
 511          'post_content' => $forum_content,
 512          'post_status'  => $forum_status,
 513          'post_parent'  => $forum_parent_id
 514      ) );
 515  
 516      // Insert forum
 517      $forum_id = wp_update_post( $forum_data );
 518  
 519      /** No Errors *************************************************************/
 520  
 521      if ( ! empty( $forum_id ) && ! is_wp_error( $forum_id ) ) {
 522  
 523          // Update counts, etc...
 524          do_action( 'bbp_edit_forum', array(
 525              'forum_id'           => $forum_id,
 526              'post_parent'        => $forum_parent_id,
 527              'forum_author'       => $forum->post_author,
 528              'last_topic_id'      => 0,
 529              'last_reply_id'      => 0,
 530              'last_active_id'     => 0,
 531              'last_active_time'   => 0,
 532              'last_active_status' => bbp_get_public_status_id()
 533          ) );
 534  
 535          /** Revisions *********************************************************/
 536  
 537          // Update locks
 538          update_post_meta( $forum_id, '_edit_last', bbp_get_current_user_id() );
 539          delete_post_meta( $forum_id, '_edit_lock' );
 540  
 541          /**
 542           * @todo omitted for now
 543          // Revision Reason
 544          if ( ! empty( $_POST['bbp_forum_edit_reason'] ) )
 545              $forum_edit_reason = sanitize_text_field( $_POST['bbp_forum_edit_reason'] );
 546  
 547          // Update revision log
 548          if ( ! empty( $_POST['bbp_log_forum_edit'] ) && ( "1" === $_POST['bbp_log_forum_edit'] ) && ( $revision_id = wp_save_post_revision( $forum_id ) ) ) {
 549              bbp_update_forum_revision_log( array(
 550                  'forum_id'    => $forum_id,
 551                  'revision_id' => $revision_id,
 552                  'author_id'   => bbp_get_current_user_id(),
 553                  'reason'      => $forum_edit_reason
 554              ) );
 555          }
 556  
 557          // If the new forum parent id is not equal to the old forum parent
 558          // id, run the bbp_move_forum action and pass the forum's parent id
 559          // as the first argument and new forum parent id as the second.
 560          // @todo implement
 561          if ( $forum_id !== $forum->post_parent ) {
 562              bbp_move_forum_handler( $forum_parent_id, $forum->post_parent, $forum_id );
 563          }
 564  
 565          */
 566  
 567          /** Additional Actions (After Save) ***********************************/
 568  
 569          do_action( 'bbp_edit_forum_post_extras', $forum_id );
 570  
 571          /** Redirect **********************************************************/
 572  
 573          // Redirect to
 574          $redirect_to = bbp_get_redirect_to();
 575  
 576          // View all?
 577          $view_all = bbp_get_view_all();
 578  
 579          // Get the forum URL
 580          $forum_url = bbp_get_forum_permalink( $forum_id, $redirect_to );
 581  
 582          // Add view all?
 583          if ( ! empty( $view_all ) ) {
 584              $forum_url = bbp_add_view_all( $forum_url );
 585          }
 586  
 587          // Allow to be filtered
 588          $forum_url = apply_filters( 'bbp_edit_forum_redirect_to', $forum_url, $view_all, $redirect_to );
 589  
 590          /** Successful Edit ***************************************************/
 591  
 592          // Redirect back to new forum
 593          bbp_redirect( $forum_url );
 594  
 595      /** Errors ****************************************************************/
 596  
 597      } else {
 598          $append_error = ( is_wp_error( $forum_id ) && $forum_id->get_error_message() ) ? $forum_id->get_error_message() . ' ' : '';
 599          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' ) );
 600      }
 601  }
 602  
 603  /**
 604   * Handle the saving of core forum metadata (Status, Visibility, and Type)
 605   *
 606   * @since 2.1.0 bbPress (r3678)
 607   *
 608   * @param int $forum_id
 609   * @return If forum ID is empty
 610   */
 611  function bbp_save_forum_extras( $forum_id = 0 ) {
 612  
 613      // Validate the forum ID
 614      $forum_id = bbp_get_forum_id( $forum_id );
 615  
 616      // Bail if forum ID is empty
 617      if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
 618          return;
 619      }
 620  
 621      /** Forum Status **********************************************************/
 622  
 623      if ( ! empty( $_POST['bbp_forum_status'] ) && in_array( $_POST['bbp_forum_status'], array( 'open', 'closed' ), true ) ) {
 624          if ( 'closed' === $_POST['bbp_forum_status'] && ! bbp_is_forum_closed( $forum_id, false ) ) {
 625              bbp_close_forum( $forum_id );
 626          } elseif ( 'open' === $_POST['bbp_forum_status'] && bbp_is_forum_open( $forum_id, false ) ) {
 627              bbp_open_forum( $forum_id );
 628          } elseif ( 'open' === $_POST['bbp_forum_status'] && bbp_is_forum_closed( $forum_id, false ) ) {
 629              bbp_open_forum( $forum_id );
 630          }
 631      }
 632  
 633      /** Forum Type ************************************************************/
 634  
 635      if ( ! empty( $_POST['bbp_forum_type'] ) && in_array( $_POST['bbp_forum_type'], array( 'forum', 'category' ), true ) ) {
 636          if ( 'category' === $_POST['bbp_forum_type'] && ! bbp_is_forum_category( $forum_id ) ) {
 637              bbp_categorize_forum( $forum_id );
 638          } elseif ( 'forum' === $_POST['bbp_forum_type'] && ! bbp_is_forum_category( $forum_id ) ) {
 639              bbp_normalize_forum( $forum_id );
 640          } elseif ( 'forum' === $_POST['bbp_forum_type'] && bbp_is_forum_category( $forum_id ) ) {
 641              bbp_normalize_forum( $forum_id );
 642          }
 643      }
 644  
 645      /** Forum Visibility ******************************************************/
 646  
 647      if ( ! empty( $_POST['bbp_forum_visibility'] ) && in_array( $_POST['bbp_forum_visibility'], array_keys( bbp_get_forum_visibilities() ), true ) ) {
 648  
 649          // Get forums current visibility
 650          $old_visibility = bbp_get_forum_visibility( $forum_id );
 651  
 652          // Sanitize the new visibility
 653          $new_visibility = sanitize_key( $_POST['bbp_forum_visibility'] );
 654  
 655          // What is the new forum visibility setting?
 656          switch ( $new_visibility ) {
 657  
 658              // Hidden
 659              case bbp_get_hidden_status_id()  :
 660                  bbp_hide_forum( $forum_id, $old_visibility );
 661                  break;
 662  
 663              // Private
 664              case bbp_get_private_status_id() :
 665                  bbp_privatize_forum( $forum_id, $old_visibility );
 666                  break;
 667  
 668              // Publish (default)
 669              case bbp_get_public_status_id()  :
 670              default :
 671                  bbp_publicize_forum( $forum_id, $old_visibility );
 672                  break;
 673          }
 674  
 675          /**
 676           * Allow custom forum visibility save actions
 677           *
 678           * @since 2.6.0 bbPress (r5855)
 679           *
 680           * @param int    $forum_id       The forum ID
 681           * @param string $old_visibility The current forum visibility
 682           * @param string $new_visibility The new forum visibility
 683           */
 684          do_action( 'bbp_update_forum_visibility', $forum_id, $old_visibility, $new_visibility );
 685      }
 686  
 687      /** Forum Moderators ******************************************************/
 688  
 689      // Either replace terms
 690      if ( bbp_allow_forum_mods() ) {
 691          if ( current_user_can( 'assign_moderators' ) && ! empty( $_POST['bbp_moderators'] ) ) {
 692  
 693              // Escape tag input
 694              $users    = sanitize_text_field( $_POST['bbp_moderators'] );
 695              $user_ids = bbp_get_user_ids_from_nicenames( $users );
 696  
 697              // Update forum moderators
 698              if ( ! empty( $user_ids ) ) {
 699  
 700                  // Remove all moderators
 701                  bbp_remove_moderator( $forum_id, null );
 702  
 703                  // Add moderators
 704                  foreach ( $user_ids as $user_id ) {
 705                      bbp_add_moderator( $forum_id, $user_id );
 706                  }
 707              }
 708  
 709          // ...or remove them.
 710          } elseif ( isset( $_POST['bbp_moderators'] ) ) {
 711              bbp_remove_moderator( $forum_id, null );
 712          }
 713      }
 714  }
 715  
 716  /** Forum Open/Close **********************************************************/
 717  
 718  /**
 719   * Closes a forum
 720   *
 721   * @since 2.0.0 bbPress (r2746)
 722   *
 723   * @param int $forum_id forum id
 724   * @return mixed False or {@link WP_Error} on failure, forum id on success
 725   */
 726  function bbp_close_forum( $forum_id = 0 ) {
 727  
 728      $forum_id = bbp_get_forum_id( $forum_id );
 729  
 730      do_action( 'bbp_close_forum',  $forum_id );
 731  
 732      update_post_meta( $forum_id, '_bbp_status', 'closed' );
 733  
 734      do_action( 'bbp_closed_forum', $forum_id );
 735  
 736      return $forum_id;
 737  }
 738  
 739  /**
 740   * Opens a forum
 741   *
 742   * @since 2.0.0 bbPress (r2746)
 743   *
 744   * @param int $forum_id forum id
 745   * @return mixed False or {@link WP_Error} on failure, forum id on success
 746   */
 747  function bbp_open_forum( $forum_id = 0 ) {
 748  
 749      $forum_id = bbp_get_forum_id( $forum_id );
 750  
 751      do_action( 'bbp_open_forum',   $forum_id );
 752  
 753      update_post_meta( $forum_id, '_bbp_status', 'open' );
 754  
 755      do_action( 'bbp_opened_forum', $forum_id );
 756  
 757      return $forum_id;
 758  }
 759  
 760  /** Forum Type ****************************************************************/
 761  
 762  /**
 763   * Make the forum a category
 764   *
 765   * @since 2.0.0 bbPress (r2746)
 766   *
 767   * @param int $forum_id Optional. Forum id
 768   * @return bool False on failure, true on success
 769   */
 770  function bbp_categorize_forum( $forum_id = 0 ) {
 771  
 772      $forum_id = bbp_get_forum_id( $forum_id );
 773  
 774      do_action( 'bbp_categorize_forum',  $forum_id );
 775  
 776      update_post_meta( $forum_id, '_bbp_forum_type', 'category' );
 777  
 778      do_action( 'bbp_categorized_forum', $forum_id );
 779  
 780      return $forum_id;
 781  }
 782  
 783  /**
 784   * Remove the category status from a forum
 785   *
 786   * @since 2.0.0 bbPress (r2746)
 787   *
 788   * @param int $forum_id Optional. Forum id
 789   * @return bool False on failure, true on success
 790   */
 791  function bbp_normalize_forum( $forum_id = 0 ) {
 792  
 793      $forum_id = bbp_get_forum_id( $forum_id );
 794  
 795      do_action( 'bbp_normalize_forum',  $forum_id );
 796  
 797      update_post_meta( $forum_id, '_bbp_forum_type', 'forum' );
 798  
 799      do_action( 'bbp_normalized_forum', $forum_id );
 800  
 801      return $forum_id;
 802  }
 803  
 804  /** Forum Visibility **********************************************************/
 805  
 806  /**
 807   * Mark the forum as public
 808   *
 809   * @since 2.0.0 bbPress (r2746)
 810   *
 811   * @param int $forum_id Optional. Forum id
 812   * @return bool False on failure, true on success
 813   */
 814  function bbp_publicize_forum( $forum_id = 0, $current_visibility = '' ) {
 815  
 816      $forum_id = bbp_get_forum_id( $forum_id );
 817  
 818      do_action( 'bbp_publicize_forum',  $forum_id );
 819  
 820      // Get private forums
 821      $private = bbp_get_private_forum_ids();
 822  
 823      // Find this forum in the array
 824      if ( in_array( $forum_id, $private, true ) ) {
 825  
 826          $offset = array_search( $forum_id, $private, true );
 827  
 828          // Splice around it
 829          array_splice( $private, $offset, 1 );
 830  
 831          // Update private forums minus this one
 832          update_option( '_bbp_private_forums', bbp_get_unique_array_values( $private ) );
 833      }
 834  
 835      // Get hidden forums
 836      $hidden = bbp_get_hidden_forum_ids();
 837  
 838      // Find this forum in the array
 839      if ( in_array( $forum_id, $hidden, true ) ) {
 840  
 841          $offset = array_search( $forum_id, $hidden, true );
 842  
 843          // Splice around it
 844          array_splice( $hidden, $offset, 1 );
 845  
 846          // Update hidden forums minus this one
 847          update_option( '_bbp_hidden_forums', bbp_get_unique_array_values( $hidden ) );
 848      }
 849  
 850      // Only run queries if visibility is changing
 851      if ( bbp_get_public_status_id() !== $current_visibility ) {
 852          $bbp_db = bbp_db();
 853          $bbp_db->update( $bbp_db->posts, array( 'post_status' => bbp_get_public_status_id() ), array( 'ID' => $forum_id ) );
 854          wp_transition_post_status( bbp_get_public_status_id(), $current_visibility, get_post( $forum_id ) );
 855          clean_post_cache( $forum_id );
 856      }
 857  
 858      do_action( 'bbp_publicized_forum', $forum_id );
 859  
 860      return $forum_id;
 861  }
 862  
 863  /**
 864   * Mark the forum as private
 865   *
 866   * @since 2.0.0 bbPress (r2746)
 867   *
 868   * @param int $forum_id Optional. Forum id
 869   * @return bool False on failure, true on success
 870   */
 871  function bbp_privatize_forum( $forum_id = 0, $current_visibility = '' ) {
 872  
 873      $forum_id = bbp_get_forum_id( $forum_id );
 874  
 875      do_action( 'bbp_privatize_forum',  $forum_id );
 876  
 877      // Only run queries if visibility is changing
 878      if ( bbp_get_private_status_id() !== $current_visibility ) {
 879  
 880          // Get hidden forums
 881          $hidden = bbp_get_hidden_forum_ids();
 882  
 883          // Find this forum in the array
 884          if ( in_array( $forum_id, $hidden, true ) ) {
 885  
 886              $offset = array_search( $forum_id, $hidden, true );
 887  
 888              // Splice around it
 889              array_splice( $hidden, $offset, 1 );
 890  
 891              // Update hidden forums minus this one
 892              update_option( '_bbp_hidden_forums', bbp_get_unique_array_values( $hidden ) );
 893          }
 894  
 895          // Add to '_bbp_private_forums' site option
 896          $private   = bbp_get_private_forum_ids();
 897          $private[] = $forum_id;
 898          update_option( '_bbp_private_forums', bbp_get_unique_array_values( $private ) );
 899  
 900          // Update forums visibility setting
 901          $bbp_db = bbp_db();
 902          $bbp_db->update( $bbp_db->posts, array( 'post_status' => bbp_get_private_status_id() ), array( 'ID' => $forum_id ) );
 903          wp_transition_post_status( bbp_get_private_status_id(), $current_visibility, get_post( $forum_id ) );
 904          clean_post_cache( $forum_id );
 905      }
 906  
 907      do_action( 'bbp_privatized_forum', $forum_id );
 908  
 909      return $forum_id;
 910  }
 911  
 912  /**
 913   * Mark the forum as hidden
 914   *
 915   * @since 2.0.0 bbPress (r2996)
 916   *
 917   * @param int $forum_id Optional. Forum id
 918   * @return bool False on failure, true on success
 919   */
 920  function bbp_hide_forum( $forum_id = 0, $current_visibility = '' ) {
 921  
 922      $forum_id = bbp_get_forum_id( $forum_id );
 923  
 924      do_action( 'bbp_hide_forum', $forum_id );
 925  
 926      // Only run queries if visibility is changing
 927      if ( bbp_get_hidden_status_id() !== $current_visibility ) {
 928  
 929          // Get private forums
 930          $private = bbp_get_private_forum_ids();
 931  
 932          // Find this forum in the array
 933          if ( in_array( $forum_id, $private, true ) ) {
 934  
 935              $offset = array_search( $forum_id, $private, true );
 936  
 937              // Splice around it
 938              array_splice( $private, $offset, 1 );
 939  
 940              // Update private forums minus this one
 941              update_option( '_bbp_private_forums', bbp_get_unique_array_values( $private ) );
 942          }
 943  
 944          // Add to '_bbp_hidden_forums' site option
 945          $hidden   = bbp_get_hidden_forum_ids();
 946          $hidden[] = $forum_id;
 947          update_option( '_bbp_hidden_forums', bbp_get_unique_array_values( $hidden ) );
 948  
 949          // Update forums visibility setting
 950          $bbp_db = bbp_db();
 951          $bbp_db->update( $bbp_db->posts, array( 'post_status' => bbp_get_hidden_status_id() ), array( 'ID' => $forum_id ) );
 952          wp_transition_post_status( bbp_get_hidden_status_id(), $current_visibility, get_post( $forum_id ) );
 953          clean_post_cache( $forum_id );
 954      }
 955  
 956      do_action( 'bbp_hid_forum',  $forum_id );
 957  
 958      return $forum_id;
 959  }
 960  
 961  /**
 962   * Recaches the private and hidden forums
 963   *
 964   * @since 2.4.0 bbPress (r5017)
 965   *
 966   * @return array An array of the status code and the message
 967   */
 968  function bbp_repair_forum_visibility() {
 969  
 970      // First, delete everything.
 971      delete_option( '_bbp_private_forums' );
 972      delete_option( '_bbp_hidden_forums'  );
 973  
 974      /**
 975       * Don't search for both private/hidden statuses. Since 'pre_get_posts' is an
 976       * action, it's not removed by suppress_filters. We need to make sure that
 977       * we're only searching for the supplied post_status.
 978       *
 979       * @see https://bbpress.trac.wordpress.org/ticket/2512
 980       */
 981      remove_action( 'pre_get_posts', 'bbp_pre_get_posts_normalize_forum_visibility', 4 );
 982  
 983      // Query for private forums
 984      $private_forums = new WP_Query( array(
 985          'fields'         => 'ids',
 986          'post_type'      => bbp_get_forum_post_type(),
 987          'post_status'    => bbp_get_private_status_id(),
 988          'posts_per_page' => -1,
 989  
 990          // Performance
 991          'nopaging'               => true,
 992          'suppress_filters'       => true,
 993          'update_post_term_cache' => false,
 994          'update_post_meta_cache' => false,
 995          'ignore_sticky_posts'    => true,
 996          'no_found_rows'          => true
 997      ) );
 998  
 999      // Query for hidden forums
1000      $hidden_forums = new WP_Query( array(
1001          'fields'           => 'ids',
1002          'suppress_filters' => true,
1003          'post_type'        => bbp_get_forum_post_type(),
1004          'post_status'      => bbp_get_hidden_status_id(),
1005          'posts_per_page'   => -1,
1006  
1007          // Performance
1008          'nopaging'               => true,
1009          'suppress_filters'       => true,
1010          'update_post_term_cache' => false,
1011          'update_post_meta_cache' => false,
1012          'ignore_sticky_posts'    => true,
1013          'no_found_rows'          => true
1014      ) );
1015  
1016      // Enable forum visibilty normalization
1017      add_action( 'pre_get_posts', 'bbp_pre_get_posts_normalize_forum_visibility', 4 );
1018  
1019      // Reset the $post global
1020      wp_reset_postdata();
1021  
1022      // Private
1023      if ( ! is_wp_error( $private_forums ) ) {
1024          update_option( '_bbp_private_forums', $private_forums->posts );
1025      }
1026  
1027      // Hidden forums
1028      if ( ! is_wp_error( $hidden_forums ) ) {
1029          update_option( '_bbp_hidden_forums',  $hidden_forums->posts  );
1030      }
1031  
1032      // Complete results
1033      return true;
1034  }
1035  
1036  /** Subscriptions *************************************************************/
1037  
1038  /**
1039   * Remove a deleted forum from all user subscriptions
1040   *
1041   * @since 2.5.0 bbPress (r5156)
1042   *
1043   * @param int $forum_id Get the forum ID to remove
1044   */
1045  function bbp_remove_forum_from_all_subscriptions( $forum_id = 0 ) {
1046  
1047      // Subscriptions are not active
1048      if ( ! bbp_is_subscriptions_active() ) {
1049          return;
1050      }
1051  
1052      // Bail if no forum
1053      $forum_id = bbp_get_forum_id( $forum_id );
1054      if ( empty( $forum_id ) ) {
1055          return;
1056      }
1057  
1058      // Remove forum from all subscriptions
1059      return bbp_remove_object_from_all_users( $forum_id, '_bbp_subscription', 'post' );
1060  }
1061  
1062  /** Count Bumpers *************************************************************/
1063  
1064  /**
1065   * Bump the total topic count of a forum
1066   *
1067   * @since 2.1.0 bbPress (r3825)
1068   *
1069   * @param int $forum_id Optional. Forum id.
1070   * @param int $difference Optional. Default 1
1071   * @param bool $update_ancestors Optional. Default true
1072   *
1073   * @return int Forum topic count
1074   */
1075  function bbp_bump_forum_topic_count( $forum_id = 0, $difference = 1, $update_ancestors = true ) {
1076  
1077      // Bail if no bump
1078      if ( empty( $difference ) ) {
1079          return false;
1080      }
1081  
1082      // Get some counts
1083      $forum_id          = bbp_get_forum_id( $forum_id );
1084      $topic_count       = bbp_get_forum_topic_count( $forum_id, false, true );
1085      $total_topic_count = bbp_get_forum_topic_count( $forum_id, true,  true );
1086      $difference        = (int) $difference;
1087  
1088      // Update this forum id
1089      update_post_meta( $forum_id, '_bbp_topic_count',       (int) ( $topic_count       + $difference ) );
1090      update_post_meta( $forum_id, '_bbp_total_topic_count', (int) ( $total_topic_count + $difference ) );
1091  
1092      // Check for ancestors
1093      if ( true === $update_ancestors ) {
1094  
1095          // Get post ancestors
1096          $forum     = get_post( $forum_id );
1097          $ancestors = get_post_ancestors( $forum );
1098  
1099          // If has ancestors, loop through them...
1100          if ( ! empty( $ancestors ) ) {
1101              foreach ( (array) $ancestors as $parent_forum_id ) {
1102  
1103                  // Only update topic count when an ancestor is not a category.
1104                  if ( ! bbp_is_forum_category( $parent_forum_id ) ) {
1105  
1106                      $parent_topic_count = bbp_get_forum_topic_count( $parent_forum_id, false, true );
1107                      update_post_meta( $parent_forum_id, '_bbp_topic_count', (int) ( $parent_topic_count + $difference ) );
1108                  }
1109  
1110                  // Update the total topic count.
1111                  $parent_total_topic_count = bbp_get_forum_topic_count( $parent_forum_id, true,  true );
1112                  update_post_meta( $parent_forum_id, '_bbp_total_topic_count', (int) ( $parent_total_topic_count + $difference ) );
1113              }
1114          }
1115      }
1116  
1117      $forum_topic_count = (int) ( $total_topic_count + $difference );
1118  
1119      // Filter & return
1120      return (int) apply_filters( 'bbp_bump_forum_topic_count', $forum_topic_count, $forum_id, $difference, $update_ancestors );
1121  }
1122  
1123  /**
1124   * Increase the total topic count of a forum by one.
1125   *
1126   * @since 2.6.0 bbPress (r6036)
1127   *
1128   * @param int $forum_id The forum id.
1129   * @return void
1130   */
1131  function bbp_increase_forum_topic_count( $forum_id = 0 ) {
1132  
1133      // Bail early if no id is passed.
1134      if ( empty( $forum_id ) ) {
1135          return;
1136      }
1137  
1138      // If it's a topic, get the forum id.
1139      if ( bbp_is_topic( $forum_id ) ) {
1140          $topic_id = $forum_id;
1141          $forum_id = bbp_get_topic_forum_id( $topic_id );
1142  
1143          // Update inverse based on item status
1144          if ( ! bbp_is_topic_public( $topic_id ) ) {
1145              bbp_increase_forum_topic_count_hidden( $forum_id );
1146              return;
1147          }
1148      }
1149  
1150      // Bump up
1151      bbp_bump_forum_topic_count( $forum_id );
1152  }
1153  
1154  /**
1155   * Decrease the total topic count of a forum by one.
1156   *
1157   * @since 2.6.0 bbPress (r6036)
1158   *
1159   * @param int $forum_id The forum id.
1160   *
1161   * @return void
1162   */
1163  function bbp_decrease_forum_topic_count( $forum_id = 0 ) {
1164  
1165      // Bail early if no id is passed.
1166      if ( empty( $forum_id ) ) {
1167          return;
1168      }
1169  
1170      // If it's a topic, get the forum id.
1171      if ( bbp_is_topic( $forum_id ) ) {
1172          $topic_id = $forum_id;
1173          $forum_id = bbp_get_topic_forum_id( $topic_id );
1174  
1175          // Update inverse based on item status
1176          if ( ! bbp_is_topic_public( $topic_id ) ) {
1177              bbp_decrease_forum_topic_count_hidden( $forum_id );
1178              return;
1179          }
1180      }
1181  
1182      // Bump down
1183      bbp_bump_forum_topic_count( $forum_id, -1 );
1184  }
1185  
1186  /**
1187   * Bump the total topic count of a forum
1188   *
1189   * @since 2.1.0 bbPress (r3825)
1190   *
1191   * @param int $forum_id Optional. Forum id.
1192   * @param int $difference Optional. Default 1
1193   * @param bool $update_ancestors Optional. Default true
1194   *
1195   * @return int Forum topic count
1196   */
1197  function bbp_bump_forum_topic_count_hidden( $forum_id = 0, $difference = 1, $update_ancestors = true ) {
1198  
1199      // Bail if no bump
1200      if ( empty( $difference ) ) {
1201          return false;
1202      }
1203  
1204      // Get some counts
1205      $forum_id          = bbp_get_forum_id( $forum_id );
1206      $reply_count       = bbp_get_forum_topic_count_hidden( $forum_id, false, true );
1207      $total_topic_count = bbp_get_forum_topic_count_hidden( $forum_id, true,  true );
1208      $difference        = (int) $difference;
1209  
1210      // Update this forum id
1211      update_post_meta( $forum_id, '_bbp_topic_count_hidden',       (int) ( $reply_count       + $difference ) );
1212      update_post_meta( $forum_id, '_bbp_total_topic_count_hidden', (int) ( $total_topic_count + $difference ) );
1213  
1214      // Check for ancestors
1215      if ( true === $update_ancestors ) {
1216  
1217          // Get post ancestors
1218          $forum     = get_post( $forum_id );
1219          $ancestors = get_post_ancestors( $forum );
1220  
1221          // If has ancestors, loop through them...
1222          if ( ! empty( $ancestors ) ) {
1223              foreach ( (array) $ancestors as $parent_forum_id ) {
1224  
1225                  // Only update topic count when an ancestor is not a category.
1226                  if ( ! bbp_is_forum_category( $parent_forum_id ) ) {
1227  
1228                      $parent_topic_count = bbp_get_forum_topic_count_hidden( $parent_forum_id, false, true );
1229                      update_post_meta( $parent_forum_id, '_bbp_topic_count_hidden', (int) ( $parent_topic_count + $difference ) );
1230                  }
1231  
1232                  // Update the total topic count.
1233                  $parent_total_topic_count = bbp_get_forum_topic_count_hidden( $parent_forum_id, true, true );
1234                  update_post_meta( $parent_forum_id, '_bbp_total_topic_count_hidden', (int) ( $parent_total_topic_count + $difference ) );
1235              }
1236          }
1237      }
1238  
1239      $forum_topic_count = (int) ( $total_topic_count + $difference );
1240  
1241      // Filter & return
1242      return (int) apply_filters( 'bbp_bump_forum_topic_count_hidden', $forum_topic_count, $forum_id, $difference, $update_ancestors );
1243  }
1244  
1245  /**
1246   * Increase the total hidden topic count of a forum by one.
1247   *
1248   * @since 2.6.0 bbPress (r6036)
1249   *
1250   * @param int $forum_id The forum id.
1251   *
1252   * @return void
1253   */
1254  function bbp_increase_forum_topic_count_hidden( $forum_id = 0 ) {
1255  
1256      // Bail early if no id is passed.
1257      if ( empty( $forum_id ) ) {
1258          return;
1259      }
1260  
1261      // If it's a topic, get the forum id.
1262      if ( bbp_is_topic( $forum_id ) ) {
1263          $topic_id = $forum_id;
1264          $forum_id = bbp_get_topic_forum_id( $topic_id );
1265  
1266          // Update inverse based on item status
1267          if ( bbp_is_topic_public( $topic_id ) ) {
1268              bbp_increase_forum_topic_count( $forum_id );
1269              return;
1270          }
1271      }
1272  
1273      // Bump up
1274      bbp_bump_forum_topic_count_hidden( $forum_id );
1275  }
1276  
1277  /**
1278   * Decrease the total hidden topic count of a forum by one.
1279   *
1280   * @since 2.6.0 bbPress (r6036)
1281   *
1282   * @param int $forum_id The forum id.
1283   *
1284   * @return void
1285   */
1286  function bbp_decrease_forum_topic_count_hidden( $forum_id = 0 ) {
1287  
1288      // Bail early if no id is passed.
1289      if ( empty( $forum_id ) ) {
1290          return;
1291      }
1292  
1293      // If it's a topic, get the forum id.
1294      if ( bbp_is_topic( $forum_id ) ) {
1295          $topic_id = $forum_id;
1296          $forum_id = bbp_get_topic_forum_id( $topic_id );
1297  
1298          // Update inverse based on item status
1299          if ( bbp_is_topic_public( $topic_id ) ) {
1300              bbp_decrease_forum_topic_count( $forum_id );
1301              return;
1302          }
1303      }
1304  
1305      // Bump down
1306      bbp_bump_forum_topic_count_hidden( $forum_id, -1 );
1307  }
1308  
1309  /**
1310   * Bump the total topic count of a forum
1311   *
1312   * @since 2.1.0 bbPress (r3825)
1313   *
1314   * @param int $forum_id Optional. Forum id.
1315   * @param int $difference Optional. Default 1
1316   * @param bool $update_ancestors Optional. Default true
1317   *
1318   * @return int Forum topic count
1319   */
1320  function bbp_bump_forum_reply_count( $forum_id = 0, $difference = 1, $update_ancestors = true ) {
1321  
1322      // Bail if no bump
1323      if ( empty( $difference ) ) {
1324          return false;
1325      }
1326  
1327      // Get some counts
1328      $forum_id          = bbp_get_forum_id( $forum_id );
1329      $reply_count       = bbp_get_forum_reply_count( $forum_id, false, true );
1330      $total_reply_count = bbp_get_forum_reply_count( $forum_id, true,  true );
1331      $difference        = (int) $difference;
1332  
1333      // Update this forum id
1334      update_post_meta( $forum_id, '_bbp_reply_count',       (int) ( $reply_count       + $difference ) );
1335      update_post_meta( $forum_id, '_bbp_total_reply_count', (int) ( $total_reply_count + $difference ) );
1336  
1337      // Check for ancestors
1338      if ( true === $update_ancestors ) {
1339  
1340          // Get post ancestors
1341          $forum     = get_post( $forum_id );
1342          $ancestors = get_post_ancestors( $forum );
1343  
1344          // If has ancestors, loop through them...
1345          if ( ! empty( $ancestors ) ) {
1346              foreach ( (array) $ancestors as $parent_forum_id ) {
1347  
1348                  // Only update reply count when an ancestor is not a category.
1349                  if ( ! bbp_is_forum_category( $parent_forum_id ) ) {
1350  
1351                      $parent_reply_count = bbp_get_forum_reply_count( $parent_forum_id, false, true );
1352                      update_post_meta( $parent_forum_id, '_bbp_reply_count', (int) ( $parent_reply_count + $difference ) );
1353                  }
1354  
1355                  // Update the total reply count.
1356                  $parent_total_reply_count = bbp_get_forum_reply_count( $parent_forum_id, true,  true );
1357                  update_post_meta( $parent_forum_id, '_bbp_total_reply_count', (int) ( $parent_total_reply_count + $difference ) );
1358              }
1359          }
1360      }
1361  
1362      $forum_reply_count = (int) ( $total_reply_count + $difference );
1363  
1364      // Filter & return
1365      return (int) apply_filters( 'bbp_bump_forum_reply_count', $forum_reply_count, $forum_id, $difference, $update_ancestors );
1366  }
1367  
1368  /**
1369   * Bump the total topic count of a forum
1370   *
1371   * @since 2.6.0 bbPress (r6922)
1372   *
1373   * @param int $forum_id Optional. Forum id.
1374   * @param int $difference Optional. Default 1
1375   * @param bool $update_ancestors Optional. Default true
1376   *
1377   * @return int Forum topic count
1378   */
1379  function bbp_bump_forum_reply_count_hidden( $forum_id = 0, $difference = 1, $update_ancestors = true ) {
1380  
1381      // Bail if no bump
1382      if ( empty( $difference ) ) {
1383          return false;
1384      }
1385  
1386      // Get some counts
1387      $forum_id          = bbp_get_forum_id( $forum_id );
1388      $reply_count       = bbp_get_forum_reply_count_hidden( $forum_id, false, true );
1389      $total_reply_count = bbp_get_forum_reply_count_hidden( $forum_id, true,  true );
1390      $difference        = (int) $difference;
1391  
1392      // Update this forum id
1393      update_post_meta( $forum_id, '_bbp_reply_count_hidden',       (int) ( $reply_count       + $difference ) );
1394      update_post_meta( $forum_id, '_bbp_total_reply_count_hidden', (int) ( $total_reply_count + $difference ) );
1395  
1396      // Check for ancestors
1397      if ( true === $update_ancestors ) {
1398  
1399          // Get post ancestors
1400          $forum     = get_post( $forum_id );
1401          $ancestors = get_post_ancestors( $forum );
1402  
1403          // If has ancestors, loop through them...
1404          if ( ! empty( $ancestors ) ) {
1405              foreach ( (array) $ancestors as $parent_forum_id ) {
1406  
1407                  // Only update reply count when an ancestor is not a category.
1408                  if ( ! bbp_is_forum_category( $parent_forum_id ) ) {
1409  
1410                      $parent_reply_count = bbp_get_forum_reply_count_hidden( $parent_forum_id, false, true );
1411                      update_post_meta( $parent_forum_id, '_bbp_reply_count_hidden', (int) ( $parent_reply_count + $difference ) );
1412                  }
1413  
1414                  // Update the total reply count.
1415                  $parent_total_reply_count = bbp_get_forum_reply_count_hidden( $parent_forum_id, true,  true );
1416                  update_post_meta( $parent_forum_id, '_bbp_total_reply_count_hidden', (int) ( $parent_total_reply_count + $difference ) );
1417              }
1418          }
1419      }
1420  
1421      $forum_reply_count = (int) ( $total_reply_count + $difference );
1422  
1423      // Filter & return
1424      return (int) apply_filters( 'bbp_bump_forum_reply_count_hidden', $forum_reply_count, $forum_id, $difference, $update_ancestors );
1425  }
1426  
1427  /**
1428   * Increase the total reply count of a forum by one.
1429   *
1430   * @since 2.6.0 bbPress (r6036)
1431   *
1432   * @param int $forum_id The forum id.
1433   *
1434   * @return void
1435   */
1436  function bbp_increase_forum_reply_count( $forum_id = 0 ) {
1437  
1438      // Bail early if no id is passed.
1439      if ( empty( $forum_id ) ) {
1440          return;
1441      }
1442  
1443      // If it's a reply, get the forum id.
1444      if ( bbp_is_reply( $forum_id ) ) {
1445          $reply_id = $forum_id;
1446          $forum_id = bbp_get_reply_forum_id( $reply_id );
1447  
1448          // Update inverse based on item status
1449          if ( ! bbp_is_reply_public( $reply_id ) ) {
1450              bbp_increase_forum_reply_count_hidden( $forum_id );
1451              return;
1452          }
1453      }
1454  
1455      // Bump up
1456      bbp_bump_forum_reply_count( $forum_id );
1457  }
1458  
1459  /**
1460   * Decrease the total reply count of a forum by one.
1461   *
1462   * @since 2.6.0 bbPress (r6036)
1463   *
1464   * @param int $forum_id The forum id.
1465   *
1466   * @return void
1467   */
1468  function bbp_decrease_forum_reply_count( $forum_id = 0 ) {
1469  
1470      // Bail early if no id is passed.
1471      if ( empty( $forum_id ) ) {
1472          return;
1473      }
1474  
1475      // If it's a reply, get the forum id.
1476      if ( bbp_is_reply( $forum_id ) ) {
1477          $reply_id = $forum_id;
1478          $forum_id = bbp_get_reply_forum_id( $reply_id );
1479  
1480          // Update inverse based on item status
1481          if ( ! bbp_is_reply_public( $reply_id ) ) {
1482              bbp_decrease_forum_reply_count_hidden( $forum_id );
1483              return;
1484          }
1485      }
1486  
1487      // Bump down
1488      bbp_bump_forum_reply_count( $forum_id, -1 );
1489  }
1490  
1491  /**
1492   * Increase the total hidden reply count of a forum by one.
1493   *
1494   * @since 2.6.0 bbPress (r6036)
1495   *
1496   * @param int $forum_id The forum id.
1497   *
1498   * @return void
1499   */
1500  function bbp_increase_forum_reply_count_hidden( $forum_id = 0 ) {
1501  
1502      // Bail early if no id is passed.
1503      if ( empty( $forum_id ) ) {
1504          return;
1505      }
1506  
1507      // If it's a reply, get the forum id.
1508      if ( bbp_is_reply( $forum_id ) ) {
1509          $reply_id = $forum_id;
1510          $forum_id = bbp_get_reply_forum_id( $reply_id );
1511  
1512          // Update inverse based on item status
1513          if ( bbp_is_reply_public( $reply_id ) ) {
1514              bbp_increase_forum_reply_count( $forum_id );
1515              return;
1516          }
1517      }
1518  
1519      // Bump up
1520      bbp_bump_forum_reply_count_hidden( $forum_id );
1521  }
1522  
1523  /**
1524   * Decrease the total hidden reply count of a forum by one.
1525   *
1526   * @since 2.6.0 bbPress (r6036)
1527   *
1528   * @param int $forum_id The forum id.
1529   *
1530   * @return void
1531   */
1532  function bbp_decrease_forum_reply_count_hidden( $forum_id = 0 ) {
1533  
1534      // Bail early if no id is passed.
1535      if ( empty( $forum_id ) ) {
1536          return;
1537      }
1538  
1539      // If it's a reply, get the forum id.
1540      if ( bbp_is_reply( $forum_id ) ) {
1541          $reply_id = $forum_id;
1542          $forum_id = bbp_get_reply_forum_id( $reply_id );
1543  
1544          // Update inverse based on item status
1545          if ( bbp_is_reply_public( $reply_id ) ) {
1546              bbp_decrease_forum_reply_count( $forum_id );
1547              return;
1548          }
1549      }
1550  
1551      // Bump down
1552      bbp_bump_forum_reply_count_hidden( $forum_id, -1 );
1553  }
1554  
1555  /**
1556   * Update forum reply counts when a topic is approved or unapproved.
1557   *
1558   * @since 2.6.0 bbPress (r6036)
1559   *
1560   * @param int $topic_id The topic id.
1561   *
1562   * @return void
1563   */
1564  function bbp_approved_unapproved_topic_update_forum_reply_count( $topic_id = 0 ) {
1565  
1566      // Bail early if we don't have a topic id.
1567      if ( empty( $topic_id ) ) {
1568          return;
1569      }
1570  
1571      // Get the topic's replies.
1572      $count = bbp_get_public_child_count( $topic_id, bbp_get_reply_post_type() );
1573  
1574      // If we're unapproving, set count to negative.
1575      if ( 'bbp_unapproved_topic' === current_filter() ) {
1576          $count = -$count;
1577      }
1578  
1579      // Bump up or down
1580      bbp_bump_forum_reply_count( bbp_get_topic_forum_id( $topic_id ), $count );
1581  }
1582  
1583  /** Forum Updaters ************************************************************/
1584  
1585  /**
1586   * Update the forum last topic id
1587   *
1588   * @since 2.0.0 bbPress (r2625)
1589   *
1590   * @param int $forum_id Optional. Forum id.
1591   * @param int $topic_id Optional. Topic id.
1592   * @return int Id of the forums most recent topic
1593   */
1594  function bbp_update_forum_last_topic_id( $forum_id = 0, $topic_id = 0 ) {
1595      $forum_id = bbp_get_forum_id( $forum_id );
1596  
1597      // Define local variable(s)
1598      $children_last_topic = 0;
1599  
1600      // Do some calculation if not manually set
1601      if ( empty( $topic_id ) ) {
1602  
1603          // Loop through children and add together forum reply counts
1604          $children = bbp_forum_query_subforum_ids( $forum_id );
1605          if ( ! empty( $children ) ) {
1606              foreach ( $children as $child ) {
1607                  $children_last_topic = bbp_update_forum_last_topic_id( $child ); // Recursive
1608              }
1609          }
1610  
1611          // Setup recent topic query vars
1612          $post_vars = array(
1613              'post_parent' => $forum_id,
1614              'post_type'   => bbp_get_topic_post_type(),
1615              'meta_key'    => '_bbp_last_active_time',
1616              'meta_type'   => 'DATETIME',
1617              'orderby'     => 'meta_value',
1618              'numberposts' => 1
1619          );
1620  
1621          // Get the most recent topic in this forum_id
1622          $recent_topic = get_posts( $post_vars );
1623          if ( ! empty( $recent_topic ) ) {
1624              $topic_id = $recent_topic[0]->ID;
1625          }
1626      }
1627  
1628      // Cast as integer in case of empty or string
1629      $topic_id            = (int) $topic_id;
1630      $children_last_topic = (int) $children_last_topic;
1631  
1632      // If child forums have higher id, use that instead
1633      if ( ! empty( $children ) && ( $children_last_topic > $topic_id ) ) {
1634          $topic_id = $children_last_topic;
1635      }
1636  
1637      // Update the last public topic ID
1638      update_post_meta( $forum_id, '_bbp_last_topic_id', $topic_id );
1639  
1640      // Filter & return
1641      return (int) apply_filters( 'bbp_update_forum_last_topic_id', $topic_id, $forum_id );
1642  }
1643  
1644  /**
1645   * Update the forum last reply id
1646   *
1647   * @since 2.0.0 bbPress (r2625)
1648   *
1649   * @param int $forum_id Optional. Forum id.
1650   * @param int $reply_id Optional. Reply id.
1651   * @return int Id of the forums most recent reply
1652   */
1653  function bbp_update_forum_last_reply_id( $forum_id = 0, $reply_id = 0 ) {
1654      $forum_id = bbp_get_forum_id( $forum_id );
1655  
1656      // Define local variable(s)
1657      $children_last_reply = 0;
1658  
1659      // Do some calculation if not manually set
1660      if ( empty( $reply_id ) ) {
1661  
1662          // Loop through children and get the most recent reply id
1663          $children = bbp_forum_query_subforum_ids( $forum_id );
1664          if ( ! empty( $children ) ) {
1665              foreach ( $children as $child ) {
1666                  $children_last_reply = bbp_update_forum_last_reply_id( $child ); // Recursive
1667              }
1668          }
1669  
1670          // If this forum has topics...
1671          $topic_ids = bbp_forum_query_topic_ids( $forum_id );
1672          if ( ! empty( $topic_ids ) ) {
1673  
1674              // ...get the most recent reply from those topics...
1675              $reply_id = bbp_forum_query_last_reply_id( $forum_id, $topic_ids );
1676  
1677              // ...and compare it to the most recent topic id...
1678              $reply_id = ( $reply_id > max( $topic_ids ) )
1679                  ? $reply_id
1680                  : max( $topic_ids );
1681          }
1682      }
1683  
1684      // Cast as integer in case of empty or string
1685      $reply_id            = (int) $reply_id;
1686      $children_last_reply = (int) $children_last_reply;
1687  
1688      // If child forums have higher ID, check for newer reply id
1689      if ( ! empty( $children ) && ( $children_last_reply > $reply_id ) ) {
1690          $reply_id = $children_last_reply;
1691      }
1692  
1693      // Update the last public reply ID
1694      update_post_meta( $forum_id, '_bbp_last_reply_id', $reply_id );
1695  
1696      // Filter & return
1697      return (int) apply_filters( 'bbp_update_forum_last_reply_id', $reply_id, $forum_id );
1698  }
1699  
1700  /**
1701   * Update the forum last active post id
1702   *
1703   * @since 2.0.0 bbPress (r2860)
1704   *
1705   * @param int $forum_id Optional. Forum id.
1706   * @param int $active_id Optional. Active post id.
1707   * @return int Id of the forums last active post
1708   */
1709  function bbp_update_forum_last_active_id( $forum_id = 0, $active_id = 0 ) {
1710  
1711      $forum_id = bbp_get_forum_id( $forum_id );
1712  
1713      // Define local variable(s)
1714      $children_last_active = 0;
1715  
1716      // Do some calculation if not manually set
1717      if ( empty( $active_id ) ) {
1718  
1719          // Loop through children and get the last active ID
1720          $children = bbp_forum_query_subforum_ids( $forum_id );
1721          if ( ! empty( $children ) ) {
1722              foreach ( $children as $child ) {
1723                  $children_last_active = bbp_update_forum_last_active_id( $child, $active_id );
1724              }
1725          }
1726  
1727          // Get topic IDs and only accept larger IDs
1728          $topic_ids = bbp_forum_query_topic_ids( $forum_id );
1729          if ( ! empty( $topic_ids ) ) {
1730  
1731              // Make sure ID is larger
1732              $active_id = bbp_forum_query_last_reply_id( $forum_id, $topic_ids );
1733              $active_id = $active_id > max( $topic_ids )
1734                  ? $active_id
1735                  : max( $topic_ids );
1736  
1737          // Forum has no topics
1738          } else {
1739              $active_id = 0;
1740          }
1741      }
1742  
1743      // Cast as integer in case of empty or string
1744      $active_id            = (int) $active_id;
1745      $children_last_active = (int) $children_last_active;
1746  
1747      // If child forums have higher ID, use that instead
1748      if ( ! empty( $children ) && ( $children_last_active > $active_id ) ) {
1749          $active_id = $children_last_active;
1750      }
1751  
1752      update_post_meta( $forum_id, '_bbp_last_active_id', $active_id );
1753  
1754      // Filter & return
1755      return (int) apply_filters( 'bbp_update_forum_last_active_id', $active_id, $forum_id );
1756  }
1757  
1758  /**
1759   * Update the forums last active date/time (aka freshness)
1760   *
1761   * @since 2.0.0 bbPress (r2680)
1762   *
1763   * @param int    $forum_id Optional. Topic id.
1764   * @param string $new_time Optional. New time in mysql format.
1765   *
1766   * @return string MySQL timestamp of last active topic or reply
1767   */
1768  function bbp_update_forum_last_active_time( $forum_id = 0, $new_time = '' ) {
1769      $forum_id = bbp_get_forum_id( $forum_id );
1770  
1771      // Check time and use current if empty
1772      if ( empty( $new_time ) ) {
1773          $new_time = get_post_field( 'post_date', bbp_get_forum_last_active_id( $forum_id ) );
1774      }
1775  
1776      // Update only if there is a time
1777      if ( ! empty( $new_time ) ) {
1778          update_post_meta( $forum_id, '_bbp_last_active_time', $new_time );
1779      }
1780  
1781      // Filter & return
1782      return apply_filters( 'bbp_update_forum_last_active', $new_time, $forum_id );
1783  }
1784  
1785  /**
1786   * Update the forum sub-forum count
1787   *
1788   * @since 2.0.0 bbPress (r2625)
1789   *
1790   * @param int $forum_id Optional. Forum id
1791   * @param int $subforums Optional. Number of subforums
1792   * @return bool True on success, false on failure
1793   */
1794  function bbp_update_forum_subforum_count( $forum_id = 0, $subforums = false ) {
1795      $forum_id = bbp_get_forum_id( $forum_id );
1796  
1797      // Maybe query for counts
1798      $subforums = ! is_int( $subforums )
1799          ? bbp_get_public_child_count( $forum_id, bbp_get_forum_post_type() )
1800          : (int) $subforums;
1801  
1802      update_post_meta( $forum_id, '_bbp_forum_subforum_count', $subforums );
1803  
1804      // Filter & return
1805      return (int) apply_filters( 'bbp_update_forum_subforum_count', $subforums, $forum_id );
1806  }
1807  
1808  /**
1809   * Adjust the total topic count of a forum
1810   *
1811   * @since 2.0.0 bbPress (r2464)
1812   *
1813   * @param int $forum_id Optional. Forum id or topic id. It is checked whether it
1814   *                       is a topic or a forum. If it's a topic, its parent,
1815   *                       i.e. the forum is automatically retrieved.
1816   * @param bool $total_count Optional. To return the total count or normal count?
1817   * @return int Forum topic count
1818   */
1819  function bbp_update_forum_topic_count( $forum_id = 0 ) {
1820      $forum_id = bbp_get_forum_id( $forum_id );
1821      $children_topic_count = 0;
1822  
1823      // Loop through subforums and add together forum topic counts
1824      $children = bbp_forum_query_subforum_ids( $forum_id );
1825      if ( ! empty( $children ) ) {
1826          foreach ( $children as $child ) {
1827              $children_topic_count += bbp_update_forum_topic_count( $child ); // Recursive
1828          }
1829      }
1830  
1831      // Get total topics for this forum
1832      $topics = bbp_get_public_child_count( $forum_id, bbp_get_topic_post_type() );
1833  
1834      // Calculate total topics in this forum
1835      $total_topics = (int) ( $topics + $children_topic_count );
1836  
1837      // Update the count
1838      update_post_meta( $forum_id, '_bbp_topic_count',       $topics       );
1839      update_post_meta( $forum_id, '_bbp_total_topic_count', $total_topics );
1840  
1841      // Filter & return
1842      return (int) apply_filters( 'bbp_update_forum_topic_count', $total_topics, $forum_id );
1843  }
1844  
1845  /**
1846   * Adjust the total hidden topic count of a forum (hidden includes trashed,
1847   * spammed and pending topics)
1848   *
1849   * @since 2.0.0 bbPress (r2888)
1850   * @since 2.6.0 bbPress (r5954) Replace direct queries with WP_Query() objects
1851   *
1852   * @param int $forum_id Optional. Topic id to update.
1853   * @param int $topic_count Optional. Set the topic count manually.
1854   *
1855   * @return int Topic hidden topic count
1856   */
1857  function bbp_update_forum_topic_count_hidden( $forum_id = 0, $topic_count = false ) {
1858  
1859      // If topic_id was passed as $forum_id, then get its forum
1860      if ( bbp_is_topic( $forum_id ) ) {
1861          $topic_id = bbp_get_topic_id( $forum_id );
1862          $forum_id = bbp_get_topic_forum_id( $topic_id );
1863  
1864      // $forum_id is not a topic_id, so validate and proceed
1865      } else {
1866          $forum_id = bbp_get_forum_id( $forum_id );
1867      }
1868  
1869      // Can't update what isn't there
1870      if ( ! empty( $forum_id ) ) {
1871  
1872          // Get topics of forum
1873          if ( ! is_int( $topic_count ) ) {
1874              $query = new WP_Query( array(
1875                  'fields'         => 'ids',
1876                  'post_parent'    => $forum_id,
1877                  'post_status'    => bbp_get_non_public_topic_statuses(),
1878                  'post_type'      => bbp_get_topic_post_type(),
1879                  'posts_per_page' => -1,
1880  
1881                  // Performance
1882                  'nopaging'               => true,
1883                  'suppress_filters'       => true,
1884                  'update_post_term_cache' => false,
1885                  'update_post_meta_cache' => false,
1886                  'ignore_sticky_posts'    => true,
1887                  'no_found_rows'          => true
1888              ) );
1889              $topic_count = $query->post_count;
1890              unset( $query );
1891          }
1892  
1893          $topic_count = (int) $topic_count;
1894  
1895          // Update the count
1896          update_post_meta( $forum_id, '_bbp_topic_count_hidden', $topic_count );
1897      }
1898  
1899      // Filter & return
1900      return (int) apply_filters( 'bbp_update_forum_topic_count_hidden', $topic_count, $forum_id );
1901  }
1902  
1903  /**
1904   * Adjust the total reply count of a forum
1905   *
1906   * @since 2.0.0 bbPress (r2464)
1907   * @since 2.6.0 bbPress (r5954) Replace direct queries with WP_Query() objects
1908   *
1909   * @param int  $forum_id Optional. Forum id or topic id. It is checked whether it
1910   *                       is a topic or a forum. If it's a topic, its parent,
1911   *                       i.e. the forum is automatically retrieved.
1912   *
1913   * @return int Forum reply count
1914   */
1915  function bbp_update_forum_reply_count( $forum_id = 0 ) {
1916  
1917      $forum_id = bbp_get_forum_id( $forum_id );
1918      $children_reply_count = 0;
1919  
1920      // Loop through children and add together forum reply counts
1921      $children = bbp_forum_query_subforum_ids( $forum_id );
1922      if ( ! empty( $children ) ) {
1923          foreach ( (array) $children as $child ) {
1924              $children_reply_count += bbp_update_forum_reply_count( $child );
1925          }
1926      }
1927  
1928      // Don't count replies if the forum is a category
1929      $reply_count = ! bbp_is_forum_category( $forum_id )
1930          ? bbp_get_public_child_count( $forum_id, bbp_get_reply_post_type() )
1931          : 0;
1932  
1933      // Calculate total replies in this forum
1934      $total_replies = (int) ( $reply_count + $children_reply_count );
1935  
1936      // Update the counts
1937      update_post_meta( $forum_id, '_bbp_reply_count',       $reply_count   );
1938      update_post_meta( $forum_id, '_bbp_total_reply_count', $total_replies );
1939  
1940      // Filter & return
1941      return (int) apply_filters( 'bbp_update_forum_reply_count', $total_replies, $forum_id );
1942  }
1943  
1944  /**
1945   * Adjust the total hidden reply count of a forum
1946   *
1947   * @since 2.6.0 bbPress (r6922)
1948   *
1949   * @param int  $forum_id Optional. Forum id or topic id. It is checked whether it
1950   *                       is a topic or a forum. If it's a topic, its parent,
1951   *                       i.e. the forum is automatically retrieved.
1952   *
1953   * @return int Forum reply count
1954   */
1955  function bbp_update_forum_reply_count_hidden( $forum_id = 0 ) {
1956  
1957      $forum_id = bbp_get_forum_id( $forum_id );
1958      $children_reply_count = 0;
1959  
1960      // Loop through children and add together forum reply counts
1961      $children = bbp_forum_query_subforum_ids( $forum_id );
1962      if ( ! empty( $children ) ) {
1963          foreach ( (array) $children as $child ) {
1964              $children_reply_count += bbp_update_forum_reply_count_hidden( $child );
1965          }
1966      }
1967  
1968      // Don't count replies if the forum is a category
1969      $reply_count = ! bbp_is_forum_category( $forum_id )
1970          ? bbp_get_non_public_child_count( $forum_id, bbp_get_reply_post_type() )
1971          : 0;
1972  
1973      // Calculate total replies in this forum
1974      $total_replies = (int) ( $reply_count + $children_reply_count );
1975  
1976      // Update the counts
1977      update_post_meta( $forum_id, '_bbp_reply_count_hidden',       $reply_count   );
1978      update_post_meta( $forum_id, '_bbp_total_reply_count_hidden', $total_replies );
1979  
1980      // Filter & return
1981      return (int) apply_filters( 'bbp_update_forum_reply_count_hidden', $total_replies, $forum_id );
1982  }
1983  
1984  /**
1985   * Updates the counts of a forum.
1986   *
1987   * This calls a few internal functions that all run manual queries against the
1988   * database to get their results. As such, this function can be costly to run
1989   * but is necessary to keep everything accurate.
1990   *
1991   * @since 2.0.0 bbPress (r2908)
1992   *
1993   * @param array $args Supports these arguments:
1994   *  - forum_id: Forum id
1995   *  - last_topic_id: Last topic id
1996   *  - last_reply_id: Last reply id
1997   *  - last_active_id: Last active post id
1998   *  - last_active_time: last active time
1999   */
2000  function bbp_update_forum( $args = array() ) {
2001  
2002      // Parse arguments against default values
2003      $r = bbp_parse_args( $args, array(
2004          'forum_id'           => 0,
2005          'post_parent'        => 0,
2006          'last_topic_id'      => 0,
2007          'last_reply_id'      => 0,
2008          'last_active_id'     => 0,
2009          'last_active_time'   => 0,
2010          'last_active_status' => bbp_get_public_status_id()
2011      ), 'update_forum' );
2012  
2013      // Update the forum parent
2014      bbp_update_forum_id( $r['forum_id'], $r['post_parent'] );
2015  
2016      // Last topic and reply ID's
2017      bbp_update_forum_last_topic_id( $r['forum_id'], $r['last_topic_id'] );
2018      bbp_update_forum_last_reply_id( $r['forum_id'], $r['last_reply_id'] );
2019  
2020      // Active dance
2021      $r['last_active_id'] = bbp_update_forum_last_active_id( $r['forum_id'], $r['last_active_id'] );
2022  
2023      // If no active time was passed, get it from the last_active_id
2024      if ( empty( $r['last_active_time'] ) ) {
2025          $r['last_active_time'] = get_post_field( 'post_date', $r['last_active_id'] );
2026      }
2027  
2028      if ( bbp_get_public_status_id() === $r['last_active_status'] ) {
2029          bbp_update_forum_last_active_time( $r['forum_id'], $r['last_active_time'] );
2030      }
2031  
2032      // Counts
2033      bbp_update_forum_subforum_count( $r['forum_id'] );
2034  
2035      // Only update topic count if we've deleted a topic
2036      if ( in_array( current_filter(), array( 'bbp_deleted_topic', 'save_post' ), true ) ) {
2037          bbp_update_forum_reply_count(        $r['forum_id'] );
2038          bbp_update_forum_topic_count(        $r['forum_id'] );
2039          bbp_update_forum_topic_count_hidden( $r['forum_id'] );
2040          bbp_update_forum_reply_count_hidden( $r['forum_id'] );
2041      }
2042  
2043      // Update the parent forum if one was passed
2044      if ( ! empty( $r['post_parent'] ) && is_numeric( $r['post_parent'] ) ) {
2045          bbp_update_forum( array(
2046              'forum_id'    => $r['post_parent'],
2047              'post_parent' => get_post_field( 'post_parent', $r['post_parent'] )
2048          ) );
2049      }
2050  
2051      // Bump the custom query cache
2052      wp_cache_set( 'last_changed', microtime(), 'bbpress_posts' );
2053  }
2054  
2055  /** Helpers *******************************************************************/
2056  
2057  /**
2058   * Return an associative array of available topic statuses
2059   *
2060   * Developers note: these statuses are actually stored as meta data, and
2061   * Visibilities are stored in post_status.
2062   *
2063   * @since 2.4.0 bbPress (r5059)
2064   *
2065   * @param int $forum_id   Optional. Forum id.
2066   *
2067   * @return array
2068   */
2069  function bbp_get_forum_statuses( $forum_id = 0 ) {
2070  
2071      // Filter & return
2072      return (array) apply_filters( 'bbp_get_forum_statuses', array(
2073          'open'   => _x( 'Open',    'Open the forum',  'bbpress' ),
2074          'closed' => _x( 'Closed',  'Close the forum', 'bbpress' )
2075      ), $forum_id );
2076  }
2077  
2078  /**
2079   * Return an associative array of forum types
2080   *
2081   * @since 2.4.0 bbPress (r5059)
2082   *
2083   * @param int $forum_id   Optional. Forum id.
2084   *
2085   * @return array
2086   */
2087  function bbp_get_forum_types( $forum_id = 0 ) {
2088  
2089      // Filter & return
2090      return (array) apply_filters( 'bbp_get_forum_types', array(
2091          'forum'    => _x( 'Forum',    'Forum accepts new topics', 'bbpress' ),
2092          'category' => _x( 'Category', 'Forum is a category',      'bbpress' )
2093      ), $forum_id );
2094  }
2095  
2096  /**
2097   * Return an associative array of forum visibility
2098   *
2099   * Developers note: these visibilities are actually stored in post_status, and
2100   * Statuses are stored in meta data.
2101   *
2102   * @since 2.4.0 bbPress (r5059)
2103   *
2104   * @param int $forum_id   Optional. Forum id.
2105   *
2106   * @return array
2107   */
2108  function bbp_get_forum_visibilities( $forum_id = 0) {
2109  
2110      // Filter & return
2111      return (array) apply_filters( 'bbp_get_forum_visibilities', array(
2112          bbp_get_public_status_id()  => _x( 'Public',  'Make forum public',  'bbpress' ),
2113          bbp_get_private_status_id() => _x( 'Private', 'Make forum private', 'bbpress' ),
2114          bbp_get_hidden_status_id()  => _x( 'Hidden',  'Make forum hidden',  'bbpress' )
2115      ), $forum_id );
2116  }
2117  
2118  /**
2119   * Return array of public forum statuses.
2120   *
2121   * @since 2.6.0 bbPress (r6921)
2122   *
2123   * @return array
2124   */
2125  function bbp_get_public_forum_statuses() {
2126      $statuses = array(
2127          bbp_get_public_status_id()
2128      );
2129  
2130      // Filter & return
2131      return (array) apply_filters( 'bbp_get_public_forum_statuses', $statuses );
2132  }
2133  
2134  /**
2135   * Return array of non-public forum statuses.
2136   *
2137   * @since 2.6.0 bbPress (r6921)
2138   *
2139   * @return array
2140   */
2141  function bbp_get_non_public_forum_statuses() {
2142      $statuses = array(
2143          bbp_get_private_status_id(),
2144          bbp_get_hidden_status_id()
2145      );
2146  
2147      // Filter & return
2148      return (array) apply_filters( 'bbp_get_non_public_forum_statuses', $statuses );
2149  }
2150  
2151  /** Queries *******************************************************************/
2152  
2153  /**
2154   * Returns the hidden forum ids
2155   *
2156   * Only hidden forum ids are returned. Public and private ids are not.
2157   *
2158   * @since 2.0.0 bbPress (r3007)
2159   */
2160  function bbp_get_hidden_forum_ids() {
2161      $forum_ids = get_option( '_bbp_hidden_forums', array() );
2162      $forum_ids = ! empty( $forum_ids )
2163          ? wp_parse_id_list( $forum_ids )
2164          : array();
2165  
2166      // Filter & return
2167      return (array) apply_filters( 'bbp_get_hidden_forum_ids', $forum_ids );
2168  }
2169  
2170  /**
2171   * Returns the private forum ids
2172   *
2173   * Only private forum ids are returned. Public and hidden ids are not.
2174   *
2175   * @since 2.0.0 bbPress (r3007)
2176   */
2177  function bbp_get_private_forum_ids() {
2178      $forum_ids = get_option( '_bbp_private_forums', array() );
2179      $forum_ids = ! empty( $forum_ids )
2180          ? wp_parse_id_list( $forum_ids )
2181          : array();
2182  
2183      // Filter & return
2184      return (array) apply_filters( 'bbp_get_private_forum_ids', $forum_ids );
2185  }
2186  
2187  /**
2188   * Returns the forum IDs that should be excluded from various views & queries,
2189   * based on the current user's capabilities.
2190   *
2191   * @since 2.6.0 bbPress (r6425)
2192   *
2193   * @return array Forum IDs to exclude, or an empty array
2194   */
2195  function bbp_get_excluded_forum_ids() {
2196  
2197      // Private forums
2198      $private = ! current_user_can( 'read_private_forums' )
2199          ? bbp_get_private_forum_ids()
2200          : array();
2201  
2202      // Hidden forums
2203      $hidden = ! current_user_can( 'read_hidden_forums' )
2204          ? bbp_get_hidden_forum_ids()
2205          : array();
2206  
2207      // Merge private & hidden forums together, and remove any empties
2208      $forum_ids = ( ! empty( $private ) || ! empty( $hidden ) )
2209          ? array_filter( wp_parse_id_list( array_merge( $private, $hidden ) ) )
2210          : array();
2211  
2212      // Filter & return
2213      return (array) apply_filters( 'bbp_get_excluded_forum_ids', $forum_ids, $private, $hidden );
2214  }
2215  
2216  /**
2217   * Returns a meta_query that either includes or excludes hidden forum IDs
2218   * from a query.
2219   *
2220   * @since 2.0.0 bbPress (r3291)
2221   *
2222   * @param string Optional. The type of value to return. (string|array|meta_query)
2223   */
2224  function bbp_exclude_forum_ids( $type = 'string' ) {
2225  
2226      // Setup arrays
2227      $forum_ids = array();
2228  
2229      // Types
2230      $types = array(
2231          'array'      => array(),
2232          'string'     => '',
2233          'meta_query' => array()
2234      );
2235  
2236      // Exclude for everyone but keymasters
2237      if ( ! bbp_is_user_keymaster() ) {
2238  
2239          // Get forum IDs to exclude
2240          $forum_ids = bbp_get_excluded_forum_ids();
2241  
2242          // Store return values in static types array
2243          if ( ! empty( $forum_ids ) ) {
2244  
2245              // Comparison
2246              $compare = ( 1 < count( $forum_ids ) )
2247                  ? 'NOT IN'
2248                  : '!=';
2249  
2250              // Setup types
2251              $types['array']      = $forum_ids;
2252              $types['string']     = implode( ',', $forum_ids );
2253              $types['meta_query'] = array(
2254                  'key'     => '_bbp_forum_id',
2255                  'value'   => $types['string'],
2256                  'type'    => 'NUMERIC',
2257                  'compare' => $compare
2258              );
2259          }
2260      }
2261  
2262      // There are forums that need to be excluded
2263      $retval = $types[ $type ];
2264  
2265      // Filter & return
2266      return apply_filters( 'bbp_exclude_forum_ids', $retval, $forum_ids, $type );
2267  }
2268  
2269  /**
2270   * Adjusts forum, topic, and reply queries to exclude items that might be
2271   * contained inside hidden or private forums that the user does not have the
2272   * capability to view.
2273   *
2274   * Doing it with an action allows us to trap all WP_Query's rather than needing
2275   * to hardcode this logic into each query. It also protects forum content for
2276   * plugins that might be doing their own queries.
2277   *
2278   * @since 2.0.0 bbPress (r3291)
2279   *
2280   * @param WP_Query $posts_query
2281   *
2282   * @return WP_Query
2283   */
2284  function bbp_pre_get_posts_normalize_forum_visibility( $posts_query = null ) {
2285  
2286      // Bail if all forums are explicitly allowed
2287      if ( true === apply_filters( 'bbp_include_all_forums', false, $posts_query ) ) {
2288          return;
2289      }
2290  
2291      // Bail if $posts_query is not an object or of incorrect class
2292      if ( ! is_object( $posts_query ) || ! is_a( $posts_query, 'WP_Query' ) ) {
2293          return;
2294      }
2295  
2296      // Get query post types array .
2297      $post_types = (array) $posts_query->get( 'post_type' );
2298  
2299      // Forums
2300      if ( bbp_get_forum_post_type() === implode( '', $post_types ) ) {
2301  
2302          // Prevent accidental wp-admin post_row override
2303          if ( is_admin() && isset( $_REQUEST['post_status'] ) ) {
2304              return;
2305          }
2306  
2307          /** Default ***********************************************************/
2308  
2309          // Add all supported forum visibilities
2310          $posts_query->set( 'post_status', array_keys( bbp_get_forum_visibilities() ) );
2311  
2312          // Get forums to exclude
2313          $hidden_ids = bbp_exclude_forum_ids( 'array' );
2314  
2315          // Bail if no forums to exclude
2316          if ( empty( $hidden_ids ) ) {
2317              return;
2318          }
2319  
2320          // Get any existing meta queries
2321          $not_in = $posts_query->get( 'post__not_in', array() );
2322  
2323          // Add our meta query to existing
2324          $not_in = array_unique( array_merge( $not_in, $hidden_ids ) );
2325  
2326          // Set the meta_query var
2327          $posts_query->set( 'post__not_in', $not_in );
2328  
2329      // Some other post type besides Forums, Topics, or Replies
2330      } elseif ( ! array_diff( $post_types, bbp_get_post_types() ) ) {
2331  
2332          // Get forums to exclude
2333          $forum_ids = bbp_exclude_forum_ids( 'meta_query' );
2334  
2335          // Bail if no forums to exclude
2336          if ( empty( $forum_ids ) ) {
2337              return;
2338          }
2339  
2340          // Get any existing meta queries
2341          $meta_query   = (array) $posts_query->get( 'meta_query', array() );
2342  
2343          // Add our meta query to existing
2344          $meta_query[] = $forum_ids;
2345  
2346          // Set the meta_query var
2347          $posts_query->set( 'meta_query', $meta_query );
2348      }
2349  }
2350  
2351  /**
2352   * Returns the forum's topic ids
2353   *
2354   * Only topics with published and closed statuses are returned
2355   *
2356   * @since 2.0.0 bbPress (r2908)
2357   *
2358   * @param int $forum_id Forum id
2359   */
2360  function bbp_forum_query_topic_ids( $forum_id ) {
2361      $topic_ids = bbp_get_public_child_ids( $forum_id, bbp_get_topic_post_type() );
2362  
2363      // Filter & return
2364      return (array) apply_filters( 'bbp_forum_query_topic_ids', $topic_ids, $forum_id );
2365  }
2366  
2367  /**
2368   * Returns the forum's subforum ids
2369   *
2370   * Only forums with published status are returned
2371   *
2372   * @since 2.0.0 bbPress (r2908)
2373   *
2374   * @param int $forum_id Forum id
2375   */
2376  function bbp_forum_query_subforum_ids( $forum_id ) {
2377      $subforum_ids = bbp_get_all_child_ids( $forum_id, bbp_get_forum_post_type() );
2378  
2379      // Filter & return
2380      return (array) apply_filters( 'bbp_forum_query_subforum_ids', $subforum_ids, $forum_id );
2381  }
2382  
2383  /**
2384   * Returns the forum's last reply id
2385   *
2386   * @since 2.0.0 bbPress (r2908)
2387   * @since 2.6.0 bbPress (r5954) Replace direct queries with WP_Query() objects
2388   *
2389   * @param int $forum_id Forum id.
2390   * @param int $topic_ids Optional. Topic ids.
2391   */
2392  function bbp_forum_query_last_reply_id( $forum_id = 0, $topic_ids = 0 ) {
2393  
2394      // Validate forum
2395      $forum_id = bbp_get_forum_id( $forum_id );
2396  
2397      // Get topic ID's if none were passed
2398      if ( empty( $topic_ids ) ) {
2399          $topic_ids = bbp_forum_query_topic_ids( $forum_id );
2400      }
2401  
2402      $query = new WP_Query( array(
2403          'fields'           => 'ids',
2404          'suppress_filters' => true,
2405          'post_parent__in'  => $topic_ids,
2406          'post_status'      => bbp_get_public_status_id(),
2407          'post_type'        => bbp_get_reply_post_type(),
2408          'posts_per_page'   => 1,
2409          'orderby'          => array(
2410              'post_date' => 'DESC',
2411              'ID'        => 'DESC'
2412          ),
2413  
2414          // Performance
2415          'update_post_term_cache' => false,
2416          'update_post_meta_cache' => false,
2417          'ignore_sticky_posts'    => true,
2418          'no_found_rows'          => true
2419      ) );
2420  
2421      $reply_id = array_shift( $query->posts );
2422  
2423      unset( $query );
2424  
2425      // Filter & return
2426      return (int) apply_filters( 'bbp_forum_query_last_reply_id', $reply_id, $forum_id );
2427  }
2428  
2429  /** Listeners *****************************************************************/
2430  
2431  /**
2432   * Check if it's a hidden forum or a topic or reply of a hidden forum and if
2433   * the user can't view it, then sets a 404
2434   *
2435   * @since 2.0.0 bbPress (r2996)
2436   */
2437  function bbp_forum_enforce_hidden() {
2438  
2439      // Bail if not viewing a single item or if user has caps
2440      if ( ! is_singular() || bbp_is_user_keymaster() || current_user_can( 'read_hidden_forums' ) ) {
2441          return;
2442      }
2443  
2444      // Define local variables
2445      $forum_id = 0;
2446      $wp_query = bbp_get_wp_query();
2447  
2448      // Check post type
2449      switch ( $wp_query->get( 'post_type' ) ) {
2450  
2451          // Forum
2452          case bbp_get_forum_post_type() :
2453              $forum_id = bbp_get_forum_id( $wp_query->post->ID );
2454              break;
2455  
2456          // Topic
2457          case bbp_get_topic_post_type() :
2458              $forum_id = bbp_get_topic_forum_id( $wp_query->post->ID );
2459              break;
2460  
2461          // Reply
2462          case bbp_get_reply_post_type() :
2463              $forum_id = bbp_get_reply_forum_id( $wp_query->post->ID );
2464              break;
2465      }
2466  
2467      // If forum is explicitly hidden and user not capable, set 404
2468      if ( ! empty( $forum_id ) && bbp_is_forum_hidden( $forum_id ) && ! current_user_can( 'read_forum', $forum_id ) ) {
2469          bbp_set_404( $wp_query );
2470      }
2471  }
2472  
2473  /**
2474   * Check if it's a private forum or a topic or reply of a private forum and if
2475   * the user can't view it, then sets a 404
2476   *
2477   * @since 2.0.0 bbPress (r2996)
2478   */
2479  function bbp_forum_enforce_private() {
2480  
2481      // Bail if not viewing a single item or if user has caps
2482      if ( ! is_singular() || bbp_is_user_keymaster() || current_user_can( 'read_private_forums' ) ) {
2483          return;
2484      }
2485  
2486      // Define local variables
2487      $forum_id = 0;
2488      $wp_query = bbp_get_wp_query();
2489  
2490      // Check post type
2491      switch ( $wp_query->get( 'post_type' ) ) {
2492  
2493          // Forum
2494          case bbp_get_forum_post_type() :
2495              $forum_id = bbp_get_forum_id( $wp_query->post->ID );
2496              break;
2497  
2498          // Topic
2499          case bbp_get_topic_post_type() :
2500              $forum_id = bbp_get_topic_forum_id( $wp_query->post->ID );
2501              break;
2502  
2503          // Reply
2504          case bbp_get_reply_post_type() :
2505              $forum_id = bbp_get_reply_forum_id( $wp_query->post->ID );
2506              break;
2507  
2508      }
2509  
2510      // If forum is explicitly hidden and user not capable, set 404
2511      if ( ! empty( $forum_id ) && bbp_is_forum_private( $forum_id ) && ! current_user_can( 'read_forum', $forum_id ) ) {
2512          bbp_set_404( $wp_query );
2513      }
2514  }
2515  
2516  /** Permissions ***************************************************************/
2517  
2518  /**
2519   * Redirect if unauthorized user is attempting to edit a forum
2520   *
2521   * @since 2.1.0 bbPress (r3607)
2522   */
2523  function bbp_check_forum_edit() {
2524  
2525      // Bail if not editing a topic
2526      if ( ! bbp_is_forum_edit() ) {
2527          return;
2528      }
2529  
2530      // User cannot edit topic, so redirect back to reply
2531      if ( ! current_user_can( 'edit_forum', bbp_get_forum_id() ) ) {
2532          bbp_redirect( bbp_get_forum_permalink() );
2533      }
2534  }
2535  
2536  /**
2537   * Delete all topics (and their replies) for a specific forum ID
2538   *
2539   * @since 2.1.0 bbPress (r3668)
2540   *
2541   * @param int $forum_id
2542   * @return If forum is not valid
2543   */
2544  function bbp_delete_forum_topics( $forum_id = 0 ) {
2545  
2546      // Validate forum ID
2547      $forum_id = bbp_get_forum_id( $forum_id );
2548      if ( empty( $forum_id ) ) {
2549          return;
2550      }
2551  
2552      // Forum is being permanently deleted, so its content has go too
2553      // Note that we get all post statuses here
2554      $topics = new WP_Query( array(
2555          'fields'         => 'id=>parent',
2556          'post_type'      => bbp_get_topic_post_type(),
2557          'post_parent'    => $forum_id,
2558          'post_status'    => array_keys( get_post_stati() ),
2559          'posts_per_page' => -1,
2560  
2561          // Performance
2562          'nopaging'               => true,
2563          'suppress_filters'       => true,
2564          'update_post_term_cache' => false,
2565          'update_post_meta_cache' => false,
2566          'ignore_sticky_posts'    => true,
2567          'no_found_rows'          => true
2568      ) );
2569  
2570      // Loop through and delete child topics. Topic replies will get deleted by
2571      // the bbp_delete_topic() action.
2572      if ( ! empty( $topics->posts ) ) {
2573          foreach ( $topics->posts as $topic ) {
2574              wp_delete_post( $topic->ID, true );
2575          }
2576  
2577          // Reset the $post global
2578          wp_reset_postdata();
2579      }
2580  
2581      // Cleanup
2582      unset( $topics );
2583  }
2584  
2585  /**
2586   * Trash all topics inside a forum
2587   *
2588   * @since 2.1.0 bbPress (r3668)
2589   *
2590   * @param int $forum_id
2591   * @return If forum is not valid
2592   */
2593  function bbp_trash_forum_topics( $forum_id = 0 ) {
2594  
2595      // Validate forum ID
2596      $forum_id = bbp_get_forum_id( $forum_id );
2597      if ( empty( $forum_id ) ) {
2598          return;
2599      }
2600  
2601      // Allowed post statuses to pre-trash
2602      $post_stati = array(
2603          bbp_get_public_status_id(),
2604          bbp_get_closed_status_id(),
2605          bbp_get_pending_status_id()
2606      );
2607  
2608      // Forum is being trashed, so its topics (and replies) are trashed too
2609      $topics = new WP_Query( array(
2610          'fields'         => 'id=>parent',
2611          'post_type'      => bbp_get_topic_post_type(),
2612          'post_parent'    => $forum_id,
2613          'post_status'    => $post_stati,
2614          'posts_per_page' => -1,
2615  
2616          // Performance
2617          'nopaging'               => true,
2618          'suppress_filters'       => true,
2619          'update_post_term_cache' => false,
2620          'update_post_meta_cache' => false,
2621          'ignore_sticky_posts'    => true,
2622          'no_found_rows'          => true
2623      ) );
2624  
2625      // Loop through and trash child topics. Topic replies will get trashed by
2626      // the bbp_trash_topic() action.
2627      if ( ! empty( $topics->posts ) ) {
2628  
2629          // Prevent debug notices
2630          $pre_trashed_topics = array();
2631  
2632          // Loop through topics, trash them, and add them to array
2633          foreach ( $topics->posts as $topic ) {
2634              wp_trash_post( $topic->ID, true );
2635              $pre_trashed_topics[] = $topic->ID;
2636          }
2637  
2638          // Set a post_meta entry of the topics that were trashed by this action.
2639          // This is so we can possibly untrash them, without untrashing topics
2640          // that were purposefully trashed before.
2641          update_post_meta( $forum_id, '_bbp_pre_trashed_topics', $pre_trashed_topics );
2642  
2643          // Reset the $post global
2644          wp_reset_postdata();
2645      }
2646  
2647      // Cleanup
2648      unset( $topics );
2649  }
2650  
2651  /**
2652   * Untrash all topics inside a forum
2653   *
2654   * @since 2.1.0 bbPress (r3668)
2655   *
2656   * @param int $forum_id
2657   * @return If forum is not valid
2658   */
2659  function bbp_untrash_forum_topics( $forum_id = 0 ) {
2660  
2661      // Validate forum ID
2662      $forum_id = bbp_get_forum_id( $forum_id );
2663  
2664      if ( empty( $forum_id ) ) {
2665          return;
2666      }
2667  
2668      // Get the topics that were not previously trashed
2669      $pre_trashed_topics = get_post_meta( $forum_id, '_bbp_pre_trashed_topics', true );
2670  
2671      // There are topics to untrash
2672      if ( ! empty( $pre_trashed_topics ) ) {
2673  
2674          // Maybe reverse the trashed topics array
2675          if ( is_array( $pre_trashed_topics ) ) {
2676              $pre_trashed_topics = array_reverse( $pre_trashed_topics );
2677          }
2678  
2679          // Loop through topics
2680          foreach ( (array) $pre_trashed_topics as $topic ) {
2681              wp_untrash_post( $topic );
2682          }
2683      }
2684  }
2685  
2686  /** Before Delete/Trash/Untrash ***********************************************/
2687  
2688  /**
2689   * Called before deleting a forum.
2690   *
2691   * This function is supplemental to the actual forum deletion which is
2692   * handled by WordPress core API functions. It is used to clean up after
2693   * a forum that is being deleted.
2694   *
2695   * @since 2.1.0 bbPress (r3668)
2696   */
2697  function bbp_delete_forum( $forum_id = 0 ) {
2698      $forum_id = bbp_get_forum_id( $forum_id );
2699  
2700      if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2701          return false;
2702      }
2703  
2704      do_action( 'bbp_delete_forum', $forum_id );
2705  }
2706  
2707  /**
2708   * Called before trashing a forum
2709   *
2710   * This function is supplemental to the actual forum being trashed which is
2711   * handled by WordPress core API functions. It is used to clean up after
2712   * a forum that is being trashed.
2713   *
2714   * @since 2.1.0 bbPress (r3668)
2715   */
2716  function bbp_trash_forum( $forum_id = 0 ) {
2717      $forum_id = bbp_get_forum_id( $forum_id );
2718  
2719      if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2720          return false;
2721      }
2722  
2723      do_action( 'bbp_trash_forum', $forum_id );
2724  }
2725  
2726  /**
2727   * Called before untrashing a forum
2728   *
2729   * @since 2.1.0 bbPress (r3668)
2730   */
2731  function bbp_untrash_forum( $forum_id = 0 ) {
2732      $forum_id = bbp_get_forum_id( $forum_id );
2733  
2734      if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2735          return false;
2736      }
2737  
2738      do_action( 'bbp_untrash_forum', $forum_id );
2739  }
2740  
2741  /** After Delete/Trash/Untrash ************************************************/
2742  
2743  /**
2744   * Called after deleting a forum
2745   *
2746   * Try not to use this action. All meta & taxonomy terms have already been
2747   * deleted, making them impossible to use.
2748   *
2749   * @since 2.1.0 bbPress (r3668)
2750   * @since 2.6.0 bbPress (r6526) Not recommend for usage
2751   */
2752  function bbp_deleted_forum( $forum_id = 0 ) {
2753      $forum_id = bbp_get_forum_id( $forum_id );
2754  
2755      if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2756          return false;
2757      }
2758  
2759      do_action( 'bbp_deleted_forum', $forum_id );
2760  }
2761  
2762  /**
2763   * Called after trashing a forum
2764   *
2765   * @since 2.1.0 bbPress (r3668)
2766   */
2767  function bbp_trashed_forum( $forum_id = 0 ) {
2768      $forum_id = bbp_get_forum_id( $forum_id );
2769  
2770      if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2771          return false;
2772      }
2773  
2774      do_action( 'bbp_trashed_forum', $forum_id );
2775  }
2776  
2777  /**
2778   * Called after untrashing a forum
2779   *
2780   * @since 2.1.0 bbPress (r3668)
2781   */
2782  function bbp_untrashed_forum( $forum_id = 0 ) {
2783      $forum_id = bbp_get_forum_id( $forum_id );
2784  
2785      if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2786          return false;
2787      }
2788  
2789      do_action( 'bbp_untrashed_forum', $forum_id );
2790  }


Generated: Mon Aug 2 01:01:34 2021 Cross-referenced by PHPXref 0.7.1