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


Generated: Thu Oct 28 01:00:54 2021 Cross-referenced by PHPXref 0.7.1