Skip to:
Content

bbPress.org

source: tags/2.6.11/src/includes/forums/functions.php

Last change on this file was 7272, checked in by johnjamesjacoby, 18 months ago

Forums: bail out of pre_get_posts if empty post_type parameter

This change addresses a regression inside of bbp_pre_get_posts_normalize_forum_visibility that was unintentionally targeting posts queries that were not sourced from the ones built into bbPress (forum/topic/reply), causing the majority of non-bbPress queries to return empty results.

Fixes #3601.

In branches/2.6, for 2.6.11.

File size: 80.3 KB
Line 
1<?php
2
3/**
4 * bbPress Forum Functions
5 *
6 * @package bbPress
7 * @subpackage Functions
8 */
9
10// Exit if accessed directly
11defined( '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 */
24function 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 */
117function 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 */
377function 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 */
619function 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 */
734function 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 */
755function 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 */
778function 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 */
799function 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 */
822function 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 */
879function 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 */
928function 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 */
976function 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 */
1053function 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 */
1083function 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 */
1139function 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 */
1171function 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 */
1205function 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 */
1262function 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 */
1294function 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 */
1328function 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 */
1387function 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 */
1444function 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 */
1476function 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 */
1508function 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 */
1540function 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 */
1572function 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 */
1602function 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 */
1661function 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 */
1717function 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 */
1776function 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 */
1802function 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 */
1827function 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 */
1865function 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 */
1923function 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 */
1963function 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 */
2008function 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 */
2077function 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 */
2095function 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 */
2116function 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 */
2133function 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 */
2149function 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 */
2168function 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 */
2185function 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 * These results are automatically filtered by bbp_allow_forums_of_user(), to
2200 * allow per-forum moderators to see forums that would otherwise be private or
2201 * hidden to them.
2202 *
2203 * If you have a need to filter these results based on your own custom
2204 * engagements API usages, please see: bbp_allow_forums_of_user()
2205 *
2206 * @since 2.6.0 bbPress (r6425)
2207 *
2208 * @return array Forum IDs to exclude, or an empty array
2209 */
2210function bbp_get_excluded_forum_ids() {
2211
2212        // Private forums
2213        $private = ! current_user_can( 'read_private_forums' )
2214                ? bbp_get_private_forum_ids()
2215                : array();
2216
2217        // Hidden forums
2218        $hidden = ! current_user_can( 'read_hidden_forums' )
2219                ? bbp_get_hidden_forum_ids()
2220                : array();
2221
2222        // Merge private & hidden forums together, and remove any empties
2223        $forum_ids = ( ! empty( $private ) || ! empty( $hidden ) )
2224                ? array_filter( wp_parse_id_list( array_merge( $private, $hidden ) ) )
2225                : array();
2226
2227        // Filter & return
2228        return (array) apply_filters( 'bbp_get_excluded_forum_ids', $forum_ids, $private, $hidden );
2229}
2230
2231/**
2232 * Returns a meta_query that either includes or excludes hidden forum IDs
2233 * from a query.
2234 *
2235 * @since 2.0.0 bbPress (r3291)
2236 *
2237 * @param string Optional. The type of value to return. (string|array|meta_query)
2238 */
2239function bbp_exclude_forum_ids( $type = 'string' ) {
2240
2241        // Setup arrays
2242        $forum_ids = array();
2243
2244        // Types
2245        $types = array(
2246                'array'      => array(),
2247                'string'     => '',
2248                'meta_query' => array()
2249        );
2250
2251        // Exclude for everyone but keymasters
2252        if ( ! bbp_is_user_keymaster() ) {
2253
2254                // Get forum IDs to exclude
2255                $forum_ids = bbp_get_excluded_forum_ids();
2256
2257                // Store return values in static types array
2258                if ( ! empty( $forum_ids ) ) {
2259
2260                        // Comparison
2261                        $compare = ( 1 < count( $forum_ids ) )
2262                                ? 'NOT IN'
2263                                : '!=';
2264
2265                        // Setup types
2266                        $types['array']      = $forum_ids;
2267                        $types['string']     = implode( ',', $forum_ids );
2268                        $types['meta_query'] = array(
2269                                'key'     => '_bbp_forum_id',
2270                                'value'   => $types['string'],
2271                                'type'    => 'NUMERIC',
2272                                'compare' => $compare
2273                        );
2274                }
2275        }
2276
2277        // There are forums that need to be excluded
2278        $retval = $types[ $type ];
2279
2280        // Filter & return
2281        return apply_filters( 'bbp_exclude_forum_ids', $retval, $forum_ids, $type );
2282}
2283
2284/**
2285 * Adjusts forum, topic, and reply queries to exclude items that might be
2286 * contained inside hidden or private forums that the user does not have the
2287 * capability to view.
2288 *
2289 * Doing it with an action allows us to trap all WP_Query's rather than needing
2290 * to hardcode this logic into each query. It also protects forum content for
2291 * plugins that might be doing their own queries.
2292 *
2293 * @since 2.0.0 bbPress (r3291)
2294 *
2295 * @param WP_Query $posts_query
2296 *
2297 * @return WP_Query
2298 */
2299function bbp_pre_get_posts_normalize_forum_visibility( $posts_query = null ) {
2300
2301        // Bail if all forums are explicitly allowed
2302        if ( true === apply_filters( 'bbp_include_all_forums', false, $posts_query ) ) {
2303                return;
2304        }
2305
2306        // Bail if $posts_query is not an object or of incorrect class
2307        if ( ! is_object( $posts_query ) || ! is_a( $posts_query, 'WP_Query' ) ) {
2308                return;
2309        }
2310
2311        // Bail to prevent unintended wp-admin post_row overrides
2312        if ( is_admin() && isset( $_REQUEST['post_status'] ) ) {
2313                return;
2314        }
2315
2316        // Get query post types as an array.
2317        $post_types = array_filter( (array) $posts_query->get( 'post_type' ) );
2318
2319        // Bail if no post types to normalize
2320        if ( empty( $post_types ) ) {
2321                return;
2322        }
2323
2324        // Forums
2325        if ( in_array( bbp_get_forum_post_type(), $post_types, true ) ) {
2326
2327                /** Default ***********************************************************/
2328
2329                // Add all supported forum visibilities
2330                $posts_query->set( 'post_status', array_keys( bbp_get_forum_visibilities() ) );
2331
2332                // Get forums to exclude
2333                $forum_ids = bbp_exclude_forum_ids( 'array' );
2334
2335                // Excluding some forums
2336                if ( ! empty( $forum_ids ) ) {
2337
2338                        // Get any existing not-in queries
2339                        $not_in = $posts_query->get( 'post__not_in', array() );
2340
2341                        // Add our not-in to existing
2342                        $not_in = array_unique( array_merge( $not_in, $forum_ids ) );
2343
2344                        // Set the new not-in val
2345                        $posts_query->set( 'post__not_in', $not_in );
2346                }
2347        }
2348
2349        // Any bbPress post type
2350        if ( ! array_diff( $post_types, bbp_get_post_types() ) ) {
2351
2352                // Get forums to exclude
2353                $forum_ids = bbp_exclude_forum_ids( 'meta_query' );
2354
2355                // Excluding some forums
2356                if ( ! empty( $forum_ids ) ) {
2357
2358                        // Get any existing meta queries
2359                        $meta_query   = (array) $posts_query->get( 'meta_query', array() );
2360
2361                        // Add our meta query to existing
2362                        $meta_query[] = $forum_ids;
2363
2364                        // Set the new meta_query val
2365                        $posts_query->set( 'meta_query', $meta_query );
2366                }
2367        }
2368}
2369
2370/**
2371 * Returns the forum's topic ids
2372 *
2373 * Only topics with published and closed statuses are returned
2374 *
2375 * @since 2.0.0 bbPress (r2908)
2376 *
2377 * @param int $forum_id Forum id
2378 */
2379function bbp_forum_query_topic_ids( $forum_id ) {
2380        $topic_ids = bbp_get_public_child_ids( $forum_id, bbp_get_topic_post_type() );
2381
2382        // Filter & return
2383        return (array) apply_filters( 'bbp_forum_query_topic_ids', $topic_ids, $forum_id );
2384}
2385
2386/**
2387 * Returns the forum's subforum ids
2388 *
2389 * Only forums with published status are returned
2390 *
2391 * @since 2.0.0 bbPress (r2908)
2392 *
2393 * @param int $forum_id Forum id
2394 */
2395function bbp_forum_query_subforum_ids( $forum_id ) {
2396        $subforum_ids = bbp_get_all_child_ids( $forum_id, bbp_get_forum_post_type() );
2397
2398        // Filter & return
2399        return (array) apply_filters( 'bbp_forum_query_subforum_ids', $subforum_ids, $forum_id );
2400}
2401
2402/**
2403 * Returns the forum's last reply id
2404 *
2405 * @since 2.0.0 bbPress (r2908)
2406 * @since 2.6.0 bbPress (r5954) Replace direct queries with WP_Query() objects
2407 *
2408 * @param int $forum_id Forum id.
2409 * @param int $topic_ids Optional. Topic ids.
2410 */
2411function bbp_forum_query_last_reply_id( $forum_id = 0, $topic_ids = 0 ) {
2412
2413        // Validate forum
2414        $forum_id = bbp_get_forum_id( $forum_id );
2415
2416        // Get topic ID's if none were passed
2417        if ( empty( $topic_ids ) ) {
2418                $topic_ids = bbp_forum_query_topic_ids( $forum_id );
2419        }
2420
2421        $query = new WP_Query( array(
2422                'fields'           => 'ids',
2423                'suppress_filters' => true,
2424                'post_parent__in'  => $topic_ids,
2425                'post_status'      => bbp_get_public_status_id(),
2426                'post_type'        => bbp_get_reply_post_type(),
2427                'posts_per_page'   => 1,
2428                'orderby'          => array(
2429                        'post_date' => 'DESC',
2430                        'ID'        => 'DESC'
2431                ),
2432
2433                // Performance
2434                'update_post_term_cache' => false,
2435                'update_post_meta_cache' => false,
2436                'ignore_sticky_posts'    => true,
2437                'no_found_rows'          => true
2438        ) );
2439
2440        $reply_id = array_shift( $query->posts );
2441
2442        unset( $query );
2443
2444        // Filter & return
2445        return (int) apply_filters( 'bbp_forum_query_last_reply_id', $reply_id, $forum_id );
2446}
2447
2448/** Listeners *****************************************************************/
2449
2450/**
2451 * Check if it's a hidden forum or a topic or reply of a hidden forum and if
2452 * the user can't view it, then sets a 404
2453 *
2454 * @since 2.0.0 bbPress (r2996)
2455 */
2456function bbp_forum_enforce_hidden() {
2457
2458        // Bail if not viewing a single item or if user has caps
2459        if ( ! is_singular() || bbp_is_user_keymaster() || current_user_can( 'read_hidden_forums' ) ) {
2460                return;
2461        }
2462
2463        // Define local variables
2464        $forum_id = 0;
2465        $wp_query = bbp_get_wp_query();
2466
2467        // Check post type
2468        switch ( $wp_query->get( 'post_type' ) ) {
2469
2470                // Forum
2471                case bbp_get_forum_post_type() :
2472                        $forum_id = bbp_get_forum_id( $wp_query->post->ID );
2473                        break;
2474
2475                // Topic
2476                case bbp_get_topic_post_type() :
2477                        $forum_id = bbp_get_topic_forum_id( $wp_query->post->ID );
2478                        break;
2479
2480                // Reply
2481                case bbp_get_reply_post_type() :
2482                        $forum_id = bbp_get_reply_forum_id( $wp_query->post->ID );
2483                        break;
2484        }
2485
2486        // If forum is explicitly hidden and user not capable, set 404
2487        if ( ! empty( $forum_id ) && bbp_is_forum_hidden( $forum_id ) && ! current_user_can( 'read_forum', $forum_id ) ) {
2488                bbp_set_404( $wp_query );
2489        }
2490}
2491
2492/**
2493 * Check if it's a private forum or a topic or reply of a private forum and if
2494 * the user can't view it, then sets a 404
2495 *
2496 * @since 2.0.0 bbPress (r2996)
2497 */
2498function bbp_forum_enforce_private() {
2499
2500        // Bail if not viewing a single item or if user has caps
2501        if ( ! is_singular() || bbp_is_user_keymaster() || current_user_can( 'read_private_forums' ) ) {
2502                return;
2503        }
2504
2505        // Define local variables
2506        $forum_id = 0;
2507        $wp_query = bbp_get_wp_query();
2508
2509        // Check post type
2510        switch ( $wp_query->get( 'post_type' ) ) {
2511
2512                // Forum
2513                case bbp_get_forum_post_type() :
2514                        $forum_id = bbp_get_forum_id( $wp_query->post->ID );
2515                        break;
2516
2517                // Topic
2518                case bbp_get_topic_post_type() :
2519                        $forum_id = bbp_get_topic_forum_id( $wp_query->post->ID );
2520                        break;
2521
2522                // Reply
2523                case bbp_get_reply_post_type() :
2524                        $forum_id = bbp_get_reply_forum_id( $wp_query->post->ID );
2525                        break;
2526
2527        }
2528
2529        // If forum is explicitly hidden and user not capable, set 404
2530        if ( ! empty( $forum_id ) && bbp_is_forum_private( $forum_id ) && ! current_user_can( 'read_forum', $forum_id ) ) {
2531                bbp_set_404( $wp_query );
2532        }
2533}
2534
2535/** Permissions ***************************************************************/
2536
2537/**
2538 * Redirect if unauthorized user is attempting to edit a forum
2539 *
2540 * @since 2.1.0 bbPress (r3607)
2541 */
2542function bbp_check_forum_edit() {
2543
2544        // Bail if not editing a topic
2545        if ( ! bbp_is_forum_edit() ) {
2546                return;
2547        }
2548
2549        // User cannot edit topic, so redirect back to reply
2550        if ( ! current_user_can( 'edit_forum', bbp_get_forum_id() ) ) {
2551                bbp_redirect( bbp_get_forum_permalink() );
2552        }
2553}
2554
2555/**
2556 * Delete all topics (and their replies) for a specific forum ID
2557 *
2558 * @since 2.1.0 bbPress (r3668)
2559 *
2560 * @param int $forum_id
2561 * @return If forum is not valid
2562 */
2563function bbp_delete_forum_topics( $forum_id = 0 ) {
2564
2565        // Validate forum ID
2566        $forum_id = bbp_get_forum_id( $forum_id );
2567        if ( empty( $forum_id ) ) {
2568                return;
2569        }
2570
2571        // Forum is being permanently deleted, so its content has go too
2572        // Note that we get all post statuses here
2573        $topics = new WP_Query( array(
2574                'fields'         => 'id=>parent',
2575                'post_type'      => bbp_get_topic_post_type(),
2576                'post_parent'    => $forum_id,
2577                'post_status'    => array_keys( get_post_stati() ),
2578                'posts_per_page' => -1,
2579
2580                // Performance
2581                'nopaging'               => true,
2582                'suppress_filters'       => true,
2583                'update_post_term_cache' => false,
2584                'update_post_meta_cache' => false,
2585                'ignore_sticky_posts'    => true,
2586                'no_found_rows'          => true
2587        ) );
2588
2589        // Loop through and delete child topics. Topic replies will get deleted by
2590        // the bbp_delete_topic() action.
2591        if ( ! empty( $topics->posts ) ) {
2592                foreach ( $topics->posts as $topic ) {
2593                        wp_delete_post( $topic->ID, true );
2594                }
2595
2596                // Reset the $post global
2597                wp_reset_postdata();
2598        }
2599
2600        // Cleanup
2601        unset( $topics );
2602}
2603
2604/**
2605 * Trash all topics inside a forum
2606 *
2607 * @since 2.1.0 bbPress (r3668)
2608 *
2609 * @param int $forum_id
2610 * @return If forum is not valid
2611 */
2612function bbp_trash_forum_topics( $forum_id = 0 ) {
2613
2614        // Validate forum ID
2615        $forum_id = bbp_get_forum_id( $forum_id );
2616        if ( empty( $forum_id ) ) {
2617                return;
2618        }
2619
2620        // Allowed post statuses to pre-trash
2621        $post_stati = array(
2622                bbp_get_public_status_id(),
2623                bbp_get_closed_status_id(),
2624                bbp_get_pending_status_id()
2625        );
2626
2627        // Forum is being trashed, so its topics (and replies) are trashed too
2628        $topics = new WP_Query( array(
2629                'fields'         => 'id=>parent',
2630                'post_type'      => bbp_get_topic_post_type(),
2631                'post_parent'    => $forum_id,
2632                'post_status'    => $post_stati,
2633                'posts_per_page' => -1,
2634
2635                // Performance
2636                'nopaging'               => true,
2637                'suppress_filters'       => true,
2638                'update_post_term_cache' => false,
2639                'update_post_meta_cache' => false,
2640                'ignore_sticky_posts'    => true,
2641                'no_found_rows'          => true
2642        ) );
2643
2644        // Loop through and trash child topics. Topic replies will get trashed by
2645        // the bbp_trash_topic() action.
2646        if ( ! empty( $topics->posts ) ) {
2647
2648                // Prevent debug notices
2649                $pre_trashed_topics = array();
2650
2651                // Loop through topics, trash them, and add them to array
2652                foreach ( $topics->posts as $topic ) {
2653                        wp_trash_post( $topic->ID, true );
2654                        $pre_trashed_topics[] = $topic->ID;
2655                }
2656
2657                // Set a post_meta entry of the topics that were trashed by this action.
2658                // This is so we can possibly untrash them, without untrashing topics
2659                // that were purposefully trashed before.
2660                update_post_meta( $forum_id, '_bbp_pre_trashed_topics', $pre_trashed_topics );
2661
2662                // Reset the $post global
2663                wp_reset_postdata();
2664        }
2665
2666        // Cleanup
2667        unset( $topics );
2668}
2669
2670/**
2671 * Untrash all topics inside a forum
2672 *
2673 * @since 2.1.0 bbPress (r3668)
2674 *
2675 * @param int $forum_id
2676 * @return If forum is not valid
2677 */
2678function bbp_untrash_forum_topics( $forum_id = 0 ) {
2679
2680        // Validate forum ID
2681        $forum_id = bbp_get_forum_id( $forum_id );
2682
2683        if ( empty( $forum_id ) ) {
2684                return;
2685        }
2686
2687        // Get the topics that were not previously trashed
2688        $pre_trashed_topics = get_post_meta( $forum_id, '_bbp_pre_trashed_topics', true );
2689
2690        // There are topics to untrash
2691        if ( ! empty( $pre_trashed_topics ) ) {
2692
2693                // Maybe reverse the trashed topics array
2694                if ( is_array( $pre_trashed_topics ) ) {
2695                        $pre_trashed_topics = array_reverse( $pre_trashed_topics );
2696                }
2697
2698                // Loop through topics
2699                foreach ( (array) $pre_trashed_topics as $topic ) {
2700                        wp_untrash_post( $topic );
2701                }
2702        }
2703}
2704
2705/** Before Delete/Trash/Untrash ***********************************************/
2706
2707/**
2708 * Called before deleting a forum.
2709 *
2710 * This function is supplemental to the actual forum deletion which is
2711 * handled by WordPress core API functions. It is used to clean up after
2712 * a forum that is being deleted.
2713 *
2714 * @since 2.1.0 bbPress (r3668)
2715 */
2716function bbp_delete_forum( $forum_id = 0 ) {
2717        $forum_id = bbp_get_forum_id( $forum_id );
2718
2719        if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2720                return false;
2721        }
2722
2723        do_action( 'bbp_delete_forum', $forum_id );
2724}
2725
2726/**
2727 * Called before trashing a forum
2728 *
2729 * This function is supplemental to the actual forum being trashed which is
2730 * handled by WordPress core API functions. It is used to clean up after
2731 * a forum that is being trashed.
2732 *
2733 * @since 2.1.0 bbPress (r3668)
2734 */
2735function bbp_trash_forum( $forum_id = 0 ) {
2736        $forum_id = bbp_get_forum_id( $forum_id );
2737
2738        if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2739                return false;
2740        }
2741
2742        do_action( 'bbp_trash_forum', $forum_id );
2743}
2744
2745/**
2746 * Called before untrashing a forum
2747 *
2748 * @since 2.1.0 bbPress (r3668)
2749 */
2750function bbp_untrash_forum( $forum_id = 0 ) {
2751        $forum_id = bbp_get_forum_id( $forum_id );
2752
2753        if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2754                return false;
2755        }
2756
2757        do_action( 'bbp_untrash_forum', $forum_id );
2758}
2759
2760/** After Delete/Trash/Untrash ************************************************/
2761
2762/**
2763 * Called after deleting a forum
2764 *
2765 * Try not to use this action. All meta & taxonomy terms have already been
2766 * deleted, making them impossible to use.
2767 *
2768 * @since 2.1.0 bbPress (r3668)
2769 * @since 2.6.0 bbPress (r6526) Not recommend for usage
2770 */
2771function bbp_deleted_forum( $forum_id = 0 ) {
2772        $forum_id = bbp_get_forum_id( $forum_id );
2773
2774        if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2775                return false;
2776        }
2777
2778        do_action( 'bbp_deleted_forum', $forum_id );
2779}
2780
2781/**
2782 * Called after trashing a forum
2783 *
2784 * @since 2.1.0 bbPress (r3668)
2785 */
2786function bbp_trashed_forum( $forum_id = 0 ) {
2787        $forum_id = bbp_get_forum_id( $forum_id );
2788
2789        if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2790                return false;
2791        }
2792
2793        do_action( 'bbp_trashed_forum', $forum_id );
2794}
2795
2796/**
2797 * Called after untrashing a forum
2798 *
2799 * @since 2.1.0 bbPress (r3668)
2800 */
2801function bbp_untrashed_forum( $forum_id = 0 ) {
2802        $forum_id = bbp_get_forum_id( $forum_id );
2803
2804        if ( empty( $forum_id ) || ! bbp_is_forum( $forum_id ) ) {
2805                return false;
2806        }
2807
2808        do_action( 'bbp_untrashed_forum', $forum_id );
2809}
Note: See TracBrowser for help on using the repository browser.