PluginProbe
bbPress / 2.1-rc2
bbPress v2.1-rc2
2.6.17 trunk 2.0 2.0-beta-1 2.0-beta-2b 2.0-beta-3 2.0-beta-3b 2.0-rc-2 2.0-rc-3 2.0-rc-4 2.0-rc-5 2.0.1 2.0.2 2.0.3 2.1 2.1-beta-1 2.1-rc1 2.1-rc2 2.1-rc3 2.1-rc4 2.1.1 2.1.2 2.1.3 2.2 2.2.1 All 72 releases
bbpress / bbp-includes / bbp-forum-functions.php

bbp-forum-functions.php in bbPress 2.1-rc2, at bbp-includes/bbp-forum-functions.php

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