PluginProbe
bbPress / 2.0-rc-5
bbPress v2.0-rc-5
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.0-rc-5, at bbp-includes/bbp-forum-functions.php

1,149 lines 36.3 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 wp_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' => 0,
37 'post_password' => '',
38 'post_content' => '',
39 'post_title' => '',
40 'menu_order' => 0,
41 );
42
43 // Parse args
44 $forum_data = wp_parse_args( $forum_data, $default_forum );
45
46 // Insert forum
47 $forum_id = wp_insert_post( $forum_data );
48
49 // Bail if no forum was added
50 if ( empty( $forum_id ) )
51 return false;
52
53 // Forum meta
54 $default_meta = array(
55 'reply_count' => 0,
56 'topic_count' => 0,
57 'topic_count_hidden' => 0,
58 'total_reply_count' => 0,
59 'total_topic_count' => 0,
60 'last_topic_id' => 0,
61 'last_reply_id' => 0,
62 'last_active_id' => 0,
63 'last_active_time' => 0,
64 'forum_subforum_count' => 0,
65 );
66
67 // Parse args
68 $forum_meta = wp_parse_args( $forum_meta, $default_meta );
69
70 // Insert forum meta
71 foreach ( $forum_meta as $meta_key => $meta_value )
72 update_post_meta( $forum_id, '_bbp_' . $meta_key, $meta_value );
73
74 // Return new forum ID
75 return $forum_id;
76 }
77
78 /** Walk **********************************************************************/
79
80 /**
81 * Walk the forum tree
82 *
83 * @param object $forums Forums
84 * @param int $depth Depth
85 * @param int $current Current forum
86 * @param array $r Parsed arguments, supported by the walker. If you want to
87 * use your own walker, pass the 'walker' arg with the walker.
88 * The walker defaults to {@link BBP_Walker_Forum}
89 * @return object Walked forum tree
90 */
91 function bbp_walk_forum( $forums, $depth, $current, $r ) {
92 $walker = empty( $r['walker'] ) ? new BBP_Walker_Forum : $r['walker'];
93 $args = array( $forums, $depth, $r, $current );
94 return call_user_func_array( array( &$walker, 'walk' ), $args );
95 }
96
97 /** Forum Actions *************************************************************/
98
99 /**
100 * Closes a forum
101 *
102 * @since bbPress (r2746)
103 *
104 * @param int $forum_id forum id
105 * @uses wp_get_single_post() To get the forum
106 * @uses do_action() Calls 'bbp_close_forum' with the forum id
107 * @uses update_post_meta() To add the previous status to a meta
108 * @uses do_action() Calls 'bbp_opened_forum' with the forum id
109 * @return mixed False or {@link WP_Error} on failure, forum id on success
110 */
111 function bbp_close_forum( $forum_id = 0 ) {
112
113 $forum_id = bbp_get_forum_id( $forum_id );
114
115 do_action( 'bbp_close_forum', $forum_id );
116
117 update_post_meta( $forum_id, '_bbp_status', 'closed' );
118
119 do_action( 'bbp_closed_forum', $forum_id );
120
121 return $forum_id;
122 }
123
124 /**
125 * Opens a forum
126 *
127 * @since bbPress (r2746)
128 *
129 * @param int $forum_id forum id
130 * @uses wp_get_single_post() To get the forum
131 * @uses do_action() Calls 'bbp_open_forum' with the forum id
132 * @uses get_post_meta() To get the previous status
133 * @uses update_post_meta() To delete the previous status meta
134 * @uses do_action() Calls 'bbp_opened_forum' with the forum id
135 * @return mixed False or {@link WP_Error} on failure, forum id on success
136 */
137 function bbp_open_forum( $forum_id = 0 ) {
138
139 $forum_id = bbp_get_forum_id( $forum_id );
140
141 do_action( 'bbp_open_forum', $forum_id );
142
143 update_post_meta( $forum_id, '_bbp_status', 'open' );
144
145 do_action( 'bbp_opened_forum', $forum_id );
146
147 return $forum_id;
148 }
149
150 /**
151 * Make the forum a category
152 *
153 * @since bbPress (r2746)
154 *
155 * @param int $forum_id Optional. Forum id
156 * @uses update_post_meta() To update the forum category meta
157 * @return bool False on failure, true on success
158 */
159 function bbp_categorize_forum( $forum_id = 0 ) {
160
161 $forum_id = bbp_get_forum_id( $forum_id );
162
163 do_action( 'bbp_categorize_forum', $forum_id );
164
165 update_post_meta( $forum_id, '_bbp_forum_type', 'category' );
166
167 do_action( 'bbp_categorized_forum', $forum_id );
168
169 return $forum_id;
170 }
171
172 /**
173 * Remove the category status from a forum
174 *
175 * @since bbPress (r2746)
176 *
177 * @param int $forum_id Optional. Forum id
178 * @uses delete_post_meta() To delete the forum category meta
179 * @return bool False on failure, true on success
180 */
181 function bbp_normalize_forum( $forum_id = 0 ) {
182
183 $forum_id = bbp_get_forum_id( $forum_id );
184
185 do_action( 'bbp_normalize_forum', $forum_id );
186
187 update_post_meta( $forum_id, '_bbp_forum_type', 'forum' );
188
189 do_action( 'bbp_normalized_forum', $forum_id );
190
191 return $forum_id;
192 }
193
194 /**
195 * Mark the forum as public
196 *
197 * @since bbPress (r2746)
198 *
199 * @param int $forum_id Optional. Forum id
200 * @uses update_post_meta() To update the forum private meta
201 * @return bool False on failure, true on success
202 */
203 function bbp_publicize_forum( $forum_id = 0, $current_visibility = '' ) {
204
205 $forum_id = bbp_get_forum_id( $forum_id );
206
207 do_action( 'bbp_publicize_forum', $forum_id );
208
209 // Only run queries if visibility is changing
210 if ( bbp_get_public_status_id() != $current_visibility ) {
211
212 // Remove from _bbp_private_forums site option
213 if ( bbp_get_private_status_id() == $current_visibility ) {
214
215 // Get private forums
216 $private = bbp_get_private_forum_ids();
217
218 // Find this forum in the array
219 if ( in_array( $forum_id, $private ) ) {
220
221 $offset = array_search( $forum_id, (array) $private );
222
223 // Splice around it
224 array_splice( $private, $offset, 1 );
225
226 // Update private forums minus this one
227 update_option( '_bbp_private_forums', array_unique( array_values( $private ) ) );
228 }
229 }
230
231 // Remove from _bbp_hidden_forums site option
232 if ( bbp_get_hidden_status_id() == $current_visibility ) {
233
234 // Get hidden forums
235 $hidden = bbp_get_hidden_forum_ids();
236
237 // Find this forum in the array
238 if ( in_array( $forum_id, $hidden ) ) {
239
240 $offset = array_search( $forum_id, (array) $hidden );
241
242 // Splice around it
243 array_splice( $hidden, $offset, 1 );
244
245 // Update hidden forums minus this one
246 update_option( '_bbp_hidden_forums', array_unique( array_values( $hidden ) ) );
247 }
248 }
249
250 // Update forum post_status
251 global $wpdb;
252 $wpdb->update( $wpdb->posts, array( 'post_status' => bbp_get_public_status_id() ), array( 'ID' => $forum_id ) );
253 wp_transition_post_status( bbp_get_public_status_id(), $current_visibility, get_post( $forum_id ) );
254 }
255
256 do_action( 'bbp_publicized_forum', $forum_id );
257
258 return $forum_id;
259 }
260
261 /**
262 * Mark the forum as private
263 *
264 * @since bbPress (r2746)
265 *
266 * @param int $forum_id Optional. Forum id
267 * @uses update_post_meta() To update the forum private meta
268 * @return bool False on failure, true on success
269 */
270 function bbp_privatize_forum( $forum_id = 0, $current_visibility = '' ) {
271
272 $forum_id = bbp_get_forum_id( $forum_id );
273
274 do_action( 'bbp_privatize_forum', $forum_id );
275
276 // Only run queries if visibility is changing
277 if ( bbp_get_private_status_id() != $current_visibility ) {
278
279 // Remove from _bbp_hidden_forums site option
280 if ( bbp_get_hidden_status_id() == $current_visibility ) {
281
282 // Get hidden forums
283 $hidden = bbp_get_hidden_forum_ids();
284
285 // Find this forum in the array
286 if ( in_array( $forum_id, $hidden ) ) {
287
288 $offset = array_search( $forum_id, (array) $hidden );
289
290 // Splice around it
291 array_splice( $hidden, $offset, 1 );
292
293 // Update hidden forums minus this one
294 update_option( '_bbp_hidden_forums', array_unique( array_values( $hidden ) ) );
295 }
296 }
297
298 // Add to '_bbp_private_forums' site option
299 $private = bbp_get_private_forum_ids();
300 $private[] = $forum_id;
301 update_option( '_bbp_private_forums', array_unique( array_values( $private ) ) );
302
303 // Update forums visibility setting
304 global $wpdb;
305 $wpdb->update( $wpdb->posts, array( 'post_status' => bbp_get_private_status_id() ), array( 'ID' => $forum_id ) );
306 wp_transition_post_status( bbp_get_private_status_id(), $current_visibility, get_post( $forum_id ) );
307 }
308
309 do_action( 'bbp_privatized_forum', $forum_id );
310
311 return $forum_id;
312 }
313
314 /**
315 * Mark the forum as hidden
316 *
317 * @since bbPress (r2996)
318 *
319 * @param int $forum_id Optional. Forum id
320 * @uses update_post_meta() To update the forum private meta
321 * @return bool False on failure, true on success
322 */
323 function bbp_hide_forum( $forum_id = 0, $current_visibility = '' ) {
324
325 $forum_id = bbp_get_forum_id( $forum_id );
326
327 do_action( 'bbp_hide_forum', $forum_id );
328
329 // Only run queries if visibility is changing
330 if ( bbp_get_hidden_status_id() != $current_visibility ) {
331
332 // Remove from _bbp_private_forums site option
333 if ( bbp_get_private_status_id() == $current_visibility ) {
334
335 // Get private forums
336 $private = bbp_get_private_forum_ids();
337
338 // Find this forum in the array
339 if ( in_array( $forum_id, $private ) ) {
340
341 $offset = array_search( $forum_id, (array) $private );
342
343 // Splice around it
344 array_splice( $private, $offset, 1 );
345
346 // Update private forums minus this one
347 update_option( '_bbp_private_forums', array_unique( array_values( $private ) ) );
348 }
349 }
350
351 // Add to '_bbp_hidden_forums' site option
352 $hidden = bbp_get_hidden_forum_ids();
353 $hidden[] = $forum_id;
354 update_option( '_bbp_hidden_forums', array_unique( array_values( $hidden ) ) );
355
356 // Update forums visibility setting
357 global $wpdb;
358 $wpdb->update( $wpdb->posts, array( 'post_status' => bbp_get_hidden_status_id() ), array( 'ID' => $forum_id ) );
359 wp_transition_post_status( bbp_get_hidden_status_id(), $current_visibility, get_post( $forum_id ) );
360 }
361
362 do_action( 'bbp_hid_forum', $forum_id );
363
364 return $forum_id;
365 }
366
367 /** Forum Updaters ************************************************************/
368
369 /**
370 * Update the forum last topic id
371 *
372 * @since bbPress (r2625)
373 *
374 * @param int $forum_id Optional. Forum id
375 * @param int $topic_id Optional. Topic id
376 * @uses bbp_get_forum_id() To get the forum id
377 * @uses bbp_forum_query_subforum_ids() To get the subforum ids
378 * @uses bbp_update_forum_last_topic_id() To update the last topic id of child
379 * forums
380 * @uses get_posts() To get the most recent topic in the forum
381 * @uses update_post_meta() To update the forum's last active id meta
382 * @uses apply_filters() Calls 'bbp_update_forum_last_topic_id' with the last
383 * reply id and forum id
384 * @return bool True on success, false on failure
385 */
386 function bbp_update_forum_last_topic_id( $forum_id = 0, $topic_id = 0 ) {
387 $forum_id = bbp_get_forum_id( $forum_id );
388
389 // Define local variable(s)
390 $children_last_topic = 0;
391
392 // Do some calculation if not manually set
393 if ( empty( $topic_id ) ) {
394
395 // Loop through children and add together forum reply counts
396 if ( $children = bbp_forum_query_subforum_ids( $forum_id ) ) {
397 foreach ( (array) $children as $child ) {
398 $children_last_topic = bbp_update_forum_last_topic_id( $child ); // Recursive
399 }
400 }
401
402 // Setup recent topic query vars
403 $post_vars = array(
404 'post_parent' => $forum_id,
405 'post_type' => bbp_get_topic_post_type(),
406 'meta_key' => '_bbp_last_active_time',
407 'orderby' => 'meta_value',
408 'numberposts' => 1
409 );
410
411 // Get the most recent topic in this forum_id
412 if ( $recent_topic = get_posts( $post_vars ) ) {
413 $topic_id = $recent_topic[0]->ID;
414 }
415 }
416
417 // Cast as integer in case of empty or string
418 $topic_id = (int) $topic_id;
419 $children_last_topic = (int) $children_last_topic;
420
421 // If child forums have higher id, use that instead
422 if ( !empty( $children ) && ( $children_last_topic > $topic_id ) )
423 $topic_id = $children_last_topic;
424
425 // Update the last public topic ID
426 if ( bbp_is_topic_published( $topic_id ) )
427 update_post_meta( $forum_id, '_bbp_last_topic_id', $topic_id );
428
429 return apply_filters( 'bbp_update_forum_last_topic_id', $topic_id, $forum_id );
430 }
431
432 /**
433 * Update the forum last reply id
434 *
435 * @since bbPress (r2625)
436 *
437 * @param int $forum_id Optional. Forum id
438 * @param int $reply_id Optional. Reply id
439 * @uses bbp_get_forum_id() To get the forum id
440 * @uses bbp_forum_query_subforum_ids() To get the subforum ids
441 * @uses bbp_update_forum_last_reply_id() To update the last reply id of child
442 * forums
443 * @uses bbp_forum_query_topic_ids() To get the topic ids in the forum
444 * @uses bbp_forum_query_last_reply_id() To get the forum's last reply id
445 * @uses bbp_is_reply_published() To make sure the reply is published
446 * @uses update_post_meta() To update the forum's last active id meta
447 * @uses apply_filters() Calls 'bbp_update_forum_last_reply_id' with the last
448 * reply id and forum id
449 * @return bool True on success, false on failure
450 */
451 function bbp_update_forum_last_reply_id( $forum_id = 0, $reply_id = 0 ) {
452 $forum_id = bbp_get_forum_id( $forum_id );
453
454 // Define local variable(s)
455 $children_last_reply = 0;
456
457 // Do some calculation if not manually set
458 if ( empty( $reply_id ) ) {
459
460 // Loop through children and get the most recent reply id
461 if ( $children = bbp_forum_query_subforum_ids( $forum_id ) ) {
462 foreach ( (array) $children as $child ) {
463 $children_last_reply = bbp_update_forum_last_reply_id( $child ); // Recursive
464 }
465 }
466
467 // If this forum has topics...
468 if ( $topic_ids = bbp_forum_query_topic_ids( $forum_id ) ) {
469
470 // ...get the most recent reply from those topics...
471 $reply_id = bbp_forum_query_last_reply_id( $forum_id, $topic_ids );
472
473 // ...and compare it to the most recent topic id...
474 $reply_id = ( $reply_id > max( $topic_ids ) ) ? $reply_id : max( $topic_ids );
475 }
476 }
477
478 // Cast as integer in case of empty or string
479 $reply_id = (int) $reply_id;
480 $children_last_reply = (int) $children_last_reply;
481
482 // If child forums have higher ID, check for newer reply id
483 if ( !empty( $children ) && ( $children_last_reply > $reply_id ) )
484 $reply_id = $children_last_reply;
485
486 // Update the last public reply ID
487 if ( bbp_is_reply_published( $reply_id ) )
488 update_post_meta( $forum_id, '_bbp_last_reply_id', $reply_id );
489
490 return apply_filters( 'bbp_update_forum_last_reply_id', $reply_id, $forum_id );
491 }
492
493 /**
494 * Update the forum last active post id
495 *
496 * @since bbPress (r2860)
497 *
498 * @param int $forum_id Optional. Forum id
499 * @param int $active_id Optional. Active post id
500 * @uses bbp_get_forum_id() To get the forum id
501 * @uses bbp_forum_query_subforum_ids() To get the subforum ids
502 * @uses bbp_update_forum_last_active_id() To update the last active id of
503 * child forums
504 * @uses bbp_forum_query_topic_ids() To get the topic ids in the forum
505 * @uses bbp_forum_query_last_reply_id() To get the forum's last reply id
506 * @uses get_post_status() To make sure the reply is published
507 * @uses update_post_meta() To update the forum's last active id meta
508 * @uses apply_filters() Calls 'bbp_update_forum_last_active_id' with the last
509 * active post id and forum id
510 * @return bool True on success, false on failure
511 */
512 function bbp_update_forum_last_active_id( $forum_id = 0, $active_id = 0 ) {
513
514 $forum_id = bbp_get_forum_id( $forum_id );
515
516 // Define local variable(s)
517 $children_last_active = 0;
518
519 // Do some calculation if not manually set
520 if ( empty( $active_id ) ) {
521
522 // Loop through children and add together forum reply counts
523 if ( $children = bbp_forum_query_subforum_ids( $forum_id ) )
524 foreach ( (array) $children as $child )
525 $children_last_active = bbp_update_forum_last_active_id ( $child, $active_id );
526
527 // Don't count replies if the forum is a category
528 if ( $topic_ids = bbp_forum_query_topic_ids( $forum_id ) ) {
529 $active_id = bbp_forum_query_last_reply_id( $forum_id, $topic_ids );
530 $active_id = $active_id > max( $topic_ids ) ? $active_id : max( $topic_ids );
531
532 // Forum has no topics
533 } else {
534 $active_id = 0;
535 }
536 }
537
538 // Cast as integer in case of empty or string
539 $active_id = (int) $active_id;
540 $children_last_active = (int) $children_last_active;
541
542 // If child forums have higher id, use that instead
543 if ( !empty( $children ) && ( $children_last_active > $active_id ) )
544 $active_id = $children_last_active;
545
546 // Update only if published
547 if ( bbp_get_public_status_id() == get_post_status( $active_id ) )
548 update_post_meta( $forum_id, '_bbp_last_active_id', (int) $active_id );
549
550 return apply_filters( 'bbp_update_forum_last_active_id', (int) $active_id, $forum_id );
551 }
552
553 /**
554 * Update the forums last active date/time (aka freshness)
555 *
556 * @since bbPress (r2680)
557 *
558 * @param int $forum_id Optional. Topic id
559 * @param string $new_time Optional. New time in mysql format
560 * @uses bbp_get_forum_id() To get the forum id
561 * @uses bbp_get_forum_last_active_id() To get the forum's last post id
562 * @uses get_post_field() To get the post date of the forum's last post
563 * @uses update_post_meta() To update the forum last active time
564 * @uses apply_filters() Calls 'bbp_update_forum_last_active' with the new time
565 * and forum id
566 * @return bool True on success, false on failure
567 */
568 function bbp_update_forum_last_active_time( $forum_id = 0, $new_time = '' ) {
569 $forum_id = bbp_get_forum_id( $forum_id );
570
571 // Check time and use current if empty
572 if ( empty( $new_time ) )
573 $new_time = get_post_field( 'post_date', bbp_get_forum_last_active_id( $forum_id ) );
574
575 // Update only if there is a time
576 if ( !empty( $new_time ) )
577 update_post_meta( $forum_id, '_bbp_last_active_time', $new_time );
578
579 return apply_filters( 'bbp_update_forum_last_active', $new_time, $forum_id );
580 }
581
582 /**
583 * Update the forum sub-forum count
584 *
585 * @since bbPress (r2625)
586 *
587 * @param int $forum_id Optional. Forum id
588 * @uses bbp_get_forum_id() To get the forum id
589 * @return bool True on success, false on failure
590 */
591 function bbp_update_forum_subforum_count( $forum_id = 0, $subforums = 0 ) {
592 $forum_id = bbp_get_forum_id( $forum_id );
593
594 if ( empty( $subforums ) )
595 $subforums = count( bbp_forum_query_subforum_ids( $forum_id ) );
596
597 update_post_meta( $forum_id, '_bbp_forum_subforum_count', (int) $subforums );
598
599 return apply_filters( 'bbp_update_forum_subforum_count', (int) $subforums, $forum_id );
600 }
601
602 /**
603 * Adjust the total topic count of a forum
604 *
605 * @since bbPress (r2464)
606 *
607 * @param int $forum_id Optional. Forum id or topic id. It is checked whether it
608 * is a topic or a forum. If it's a topic, its parent,
609 * i.e. the forum is automatically retrieved.
610 * @param bool $total_count Optional. To return the total count or normal
611 * count?
612 * @uses bbp_get_forum_id() To get the forum id
613 * @uses bbp_forum_query_subforum_ids() To get the subforum ids
614 * @uses bbp_update_forum_topic_count() To update the forum topic count
615 * @uses bbp_forum_query_topic_ids() To get the forum topic ids
616 * @uses update_post_meta() To update the forum's topic count meta
617 * @uses apply_filters() Calls 'bbp_update_forum_topic_count' with the topic
618 * count and forum id
619 * @return int Forum topic count
620 */
621 function bbp_update_forum_topic_count( $forum_id = 0 ) {
622 $forum_id = bbp_get_forum_id( $forum_id );
623 $children_topic_count = 0;
624
625 // Loop through subforums and add together forum topic counts
626 if ( $children = bbp_forum_query_subforum_ids( $forum_id ) ) {
627 foreach ( (array) $children as $child ) {
628 $children_topic_count += bbp_update_forum_topic_count( $child ); // Recursive
629 }
630 }
631
632 // Get total topics for this forum
633 $topics = (int) count( bbp_forum_query_topic_ids( $forum_id ) );
634
635 // Calculate total topics in this forum
636 $total_topics = $topics + $children_topic_count;
637
638 // Update the count
639 update_post_meta( $forum_id, '_bbp_topic_count', (int) $topics );
640 update_post_meta( $forum_id, '_bbp_total_topic_count', (int) $total_topics );
641
642 return apply_filters( 'bbp_update_forum_topic_count', (int) $total_topics, $forum_id );
643 }
644
645 /**
646 * Adjust the total hidden topic count of a forum (hidden includes trashed and spammed topics)
647 *
648 * @since bbPress (r2888)
649 *
650 * @param int $forum_id Optional. Topic id to update
651 * @param int $topic_count Optional. Set the topic count manually
652 * @uses bbp_is_topic() To check if the supplied id is a topic
653 * @uses bbp_get_topic_id() To get the topic id
654 * @uses bbp_get_topic_forum_id() To get the topic forum id
655 * @uses bbp_get_forum_id() To get the forum id
656 * @uses wpdb::prepare() To prepare our sql query
657 * @uses wpdb::get_col() To execute our query and get the column back
658 * @uses update_post_meta() To update the forum hidden topic count meta
659 * @uses apply_filters() Calls 'bbp_update_forum_topic_count_hidden' with the
660 * hidden topic count and forum id
661 * @return int Topic hidden topic count
662 */
663 function bbp_update_forum_topic_count_hidden( $forum_id = 0, $topic_count = 0 ) {
664 global $wpdb;
665
666 // If topic_id was passed as $forum_id, then get its forum
667 if ( bbp_is_topic( $forum_id ) ) {
668 $topic_id = bbp_get_topic_id( $forum_id );
669 $forum_id = bbp_get_topic_forum_id( $topic_id );
670
671 // $forum_id is not a topic_id, so validate and proceed
672 } else {
673 $forum_id = bbp_get_forum_id( $forum_id );
674 }
675
676 // Can't update what isn't there
677 if ( !empty( $forum_id ) ) {
678
679 // Get topics of forum
680 if ( empty( $topic_count ) )
681 $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() ) );
682
683 // Update the count
684 update_post_meta( $forum_id, '_bbp_topic_count_hidden', (int) $topic_count );
685 }
686
687 return apply_filters( 'bbp_update_forum_topic_count_hidden', (int) $topic_count, $forum_id );
688 }
689
690 /**
691 * Adjust the total reply count of a forum
692 *
693 * @since bbPress (r2464)
694 *
695 * @param int $forum_id Optional. Forum id or topic id. It is checked whether it
696 * is a topic or a forum. If it's a topic, its parent,
697 * i.e. the forum is automatically retrieved.
698 * @param bool $total_count Optional. To return the total count or normal
699 * count?
700 * @uses bbp_get_forum_id() To get the forum id
701 * @uses bbp_forum_query_subforum_ids() To get the subforum ids
702 * @uses bbp_update_forum_reply_count() To update the forum reply count
703 * @uses bbp_forum_query_topic_ids() To get the forum topic ids
704 * @uses wpdb::prepare() To prepare the sql statement
705 * @uses wpdb::get_var() To execute the query and get the var back
706 * @uses update_post_meta() To update the forum's reply count meta
707 * @uses apply_filters() Calls 'bbp_update_forum_topic_count' with the reply
708 * count and forum id
709 * @return int Forum reply count
710 */
711 function bbp_update_forum_reply_count( $forum_id = 0 ) {
712 global $wpdb;
713
714 $forum_id = bbp_get_forum_id( $forum_id );
715 $children_reply_count = 0;
716
717 // Loop through children and add together forum reply counts
718 if ( $children = bbp_forum_query_subforum_ids( $forum_id ) )
719 foreach ( (array) $children as $child )
720 $children_reply_count += bbp_update_forum_reply_count( $child );
721
722 // Don't count replies if the forum is a category
723 if ( $topic_ids = bbp_forum_query_topic_ids( $forum_id ) )
724 $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() ) );
725 else
726 $reply_count = 0;
727
728 // Calculate total replies in this forum
729 $total_replies = (int) $reply_count + $children_reply_count;
730
731 // Update the count
732 update_post_meta( $forum_id, '_bbp_reply_count', $reply_count );
733 update_post_meta( $forum_id, '_bbp_total_reply_count', $total_replies );
734
735 return apply_filters( 'bbp_update_forum_reply_count', $total_replies, $forum_id );
736 }
737
738 /**
739 * Updates the counts of a forum.
740 *
741 * This calls a few internal functions that all run manual queries against the
742 * database to get their results. As such, this function can be costly to run
743 * but is necessary to keep everything accurate.
744 *
745 * @since bbPress (r2908)
746 *
747 * @param mixed $args Supports these arguments:
748 * - forum_id: Forum id
749 * - last_topic_id: Last topic id
750 * - last_reply_id: Last reply id
751 * - last_active_id: Last active post id
752 * - last_active_time: last active time
753 * @uses bbp_update_forum_last_topic_id() To update the forum last topic id
754 * @uses bbp_update_forum_last_reply_id() To update the forum last reply id
755 * @uses bbp_update_forum_last_active_id() To update the last active post id
756 * @uses get_post_field() To get the post date of the last active id
757 * @uses bbp_update_forum_last_active_time() To update the last active time
758 * @uses bbp_update_forum_subforum_count() To update the subforum count
759 * @uses bbp_update_forum_topic_count() To update the forum topic count
760 * @uses bbp_update_forum_reply_count() To update the forum reply count
761 * @uses bbp_update_forum_topic_count_hidden() To update the hidden topic count
762 */
763 function bbp_update_forum( $args = '' ) {
764 $defaults = array(
765 'forum_id' => 0,
766 'post_parent' => 0,
767 'last_topic_id' => 0,
768 'last_reply_id' => 0,
769 'last_active_id' => 0,
770 'last_active_time' => 0,
771 'last_active_status' => bbp_get_public_status_id()
772 );
773
774 $r = wp_parse_args( $args, $defaults );
775 extract( $r );
776
777 // Last topic and reply ID's
778 bbp_update_forum_last_topic_id( $forum_id, $last_topic_id );
779 bbp_update_forum_last_reply_id( $forum_id, $last_reply_id );
780
781 // Active dance
782 $last_active_id = bbp_update_forum_last_active_id( $forum_id, $last_active_id );
783
784 // If no active time was passed, get it from the last_active_id
785 if ( empty( $last_active_time ) )
786 $last_active_time = get_post_field( 'post_date', $last_active_id );
787
788 if ( bbp_get_public_status_id() == $last_active_status ) {
789 bbp_update_forum_last_active_time( $forum_id, $last_active_time );
790 }
791
792 // Counts
793 bbp_update_forum_subforum_count ( $forum_id );
794 bbp_update_forum_reply_count ( $forum_id );
795 bbp_update_forum_topic_count ( $forum_id );
796 bbp_update_forum_topic_count_hidden( $forum_id );
797
798 // Update the parent forum if one was passed
799 if ( !empty( $post_parent ) && is_numeric( $post_parent ) ) {
800 bbp_update_forum( array(
801 'forum_id' => $post_parent,
802 'post_parent' => get_post_field( 'post_parent', $post_parent )
803 ) );
804 }
805 }
806
807 /** Queries *******************************************************************/
808
809 /**
810 * Returns the hidden forum ids
811 *
812 * Only hidden forum ids are returned. Public and private ids are not.
813 *
814 * @since bbPress (r3007)
815 *
816 * @uses get_option() Returns the unserialized array of hidden forum ids
817 * @uses apply_filters() Calls 'bbp_forum_query_topic_ids' with the topic ids
818 * and forum id
819 */
820 function bbp_get_hidden_forum_ids() {
821 $forum_ids = get_option( '_bbp_hidden_forums', array() );
822
823 return apply_filters( 'bbp_get_hidden_forum_ids', (array) $forum_ids );
824 }
825
826 /**
827 * Returns the private forum ids
828 *
829 * Only private forum ids are returned. Public and hidden ids are not.
830 *
831 * @since bbPress (r3007)
832 *
833 * @uses get_option() Returns the unserialized array of private forum ids
834 * @uses apply_filters() Calls 'bbp_forum_query_topic_ids' with the topic ids
835 * and forum id
836 */
837 function bbp_get_private_forum_ids() {
838 $forum_ids = get_option( '_bbp_private_forums', array() );
839
840 return apply_filters( 'bbp_get_private_forum_ids', (array) $forum_ids );
841 }
842
843 /**
844 * Returns a meta_query that either includes or excludes hidden forum IDs
845 * from a query.
846 *
847 * @since bbPress (r3291)
848 *
849 * @param string Optional. The type of value to return. (string|array|meta_query)
850 *
851 * @uses is_super_admin()
852 * @uses bbp_is_user_home()
853 * @uses bbp_get_hidden_forum_ids()
854 * @uses bbp_get_private_forum_ids()
855 * @uses apply_filters()
856 */
857 function bbp_exclude_forum_ids( $type = 'string' ) {
858
859 // Setup arrays
860 $retval = $private = $hidden = $meta_query = $forum_ids = array();
861
862 // Exclude for everyone but super admins
863 if ( !is_super_admin() ) {
864
865 // Private forums
866 if ( !current_user_can( 'read_private_forums' ) )
867 $private = bbp_get_private_forum_ids();
868
869 // Hidden forums
870 if ( !current_user_can( 'read_hidden_forums' ) )
871 $hidden = bbp_get_hidden_forum_ids();
872
873 // Merge private and hidden forums together
874 $forum_ids = (array) array_filter( array_merge( $private, $hidden ) );
875
876 // There are forums that need to be excluded
877 if ( !empty( $forum_ids ) ) {
878
879 switch ( $type ) {
880
881 // Separate forum ID's into a comma separated string
882 case 'string' :
883 $retval = implode( ',', $forum_ids );
884 break;
885
886 // Use forum_ids array
887 case 'array' :
888 $retval = $forum_ids;
889 break;
890
891 // Build a meta_query
892 case 'meta_query' :
893 $retval = array(
894 'key' => '_bbp_forum_id',
895 'value' => implode( ',', $forum_ids ),
896 'compare' => ( 1 < count( $forum_ids ) ) ? 'NOT IN' : '!='
897 );
898 break;
899 }
900 }
901 }
902
903 // Filter and return the results
904 return apply_filters( 'bbp_exclude_forum_ids', $retval, $forum_ids, $type );
905 }
906
907 /**
908 * Adjusts topic and reply queries to exclude items that might be contained
909 * inside hidden or private forums that the user does not have the capability
910 * to view.
911 *
912 * @since bbPress (r3291)
913 *
914 * @param WP_Query $posts_query
915 *
916 * @uses apply_filters()
917 * @uses bbp_exclude_forum_ids()
918 * @uses bbp_get_topic_post_type()
919 * @uses bbp_get_reply_post_type()
920
921 * @return WP_Query
922 */
923 function bbp_pre_get_posts_exclude_forums( $posts_query ) {
924
925 // Bail if all forums are explicitly allowed
926 if ( true === apply_filters( 'bbp_include_all_forums', $posts_query ) )
927 return $posts_query;
928
929 // Bail if $posts_query is not an object or of incorrect class
930 if ( !is_object( $posts_query ) || ( 'WP_Query' != get_class( $posts_query ) ) )
931 return $posts_query;
932
933 // Bail if filters are suppressed on this query
934 if ( true == $posts_query->get( 'suppress_filters' ) )
935 return $posts_query;
936
937 // There are forums that need to be excluded
938 if ( $forum_ids = bbp_exclude_forum_ids( 'meta_query' ) ) {
939
940 // Only exclude forums on bbPress queries
941 switch ( $posts_query->get( 'post_type' ) ) {
942
943 // Topics
944 case bbp_get_topic_post_type() :
945
946 // Replies
947 case bbp_get_reply_post_type() :
948
949 // Topics and replies
950 case array( bbp_get_topic_post_type(), bbp_get_reply_post_type() ) :
951
952 // Get any existing meta queries
953 $meta_query = $posts_query->get( 'meta_query' );
954
955 // Add our meta query to existing
956 $meta_query[] = $forum_ids;
957
958 // Set the meta_query var
959 $posts_query->set( 'meta_query', $meta_query );
960
961 break;
962 }
963 }
964
965 // Return possibly adjusted query
966 return $posts_query;
967 }
968
969 /**
970 * Returns the forum's topic ids
971 *
972 * Only topics with published and closed statuses are returned
973 *
974 * @since bbPress (r2908)
975 *
976 * @param int $forum_id Forum id
977 * @uses bbp_get_topic_post_type() To get the topic post type
978 * @uses bbp_get_public_child_ids() To get the topic ids
979 * @uses apply_filters() Calls 'bbp_forum_query_topic_ids' with the topic ids
980 * and forum id
981 */
982 function bbp_forum_query_topic_ids( $forum_id ) {
983 $topic_ids = bbp_get_public_child_ids( $forum_id, bbp_get_topic_post_type() );
984
985 return apply_filters( 'bbp_forum_query_topic_ids', $topic_ids, $forum_id );
986 }
987
988 /**
989 * Returns the forum's subforum ids
990 *
991 * Only forums with published status are returned
992 *
993 * @since bbPress (r2908)
994 *
995 * @param int $forum_id Forum id
996 * @uses bbp_get_forum_post_type() To get the forum post type
997 * @uses bbp_get_public_child_ids() To get the forum ids
998 * @uses apply_filters() Calls 'bbp_forum_query_subforum_ids' with the subforum
999 * ids and forum id
1000 */
1001 function bbp_forum_query_subforum_ids( $forum_id ) {
1002 $subforum_ids = bbp_get_public_child_ids( $forum_id, bbp_get_forum_post_type() );
1003
1004 return apply_filters( 'bbp_get_forum_subforum_ids', $subforum_ids, $forum_id );
1005 }
1006
1007 /**
1008 * Returns the forum's last reply id
1009 *
1010 * @since bbPress (r2908)
1011 *
1012 * @param int $forum_id Forum id
1013 * @param int $topic_ids Optional. Topic ids
1014 * @uses wp_cache_get() To check for cache and retrieve it
1015 * @uses bbp_forum_query_topic_ids() To get the forum's topic ids
1016 * @uses wpdb::prepare() To prepare the query
1017 * @uses wpdb::get_var() To execute the query and get the var back
1018 * @uses bbp_get_reply_post_type() To get the reply post type
1019 * @uses wp_cache_set() To set the cache for future use
1020 * @uses apply_filters() Calls 'bbp_forum_query_last_reply_id' with the reply id
1021 * and forum id
1022 */
1023 function bbp_forum_query_last_reply_id( $forum_id, $topic_ids = 0 ) {
1024 global $wpdb;
1025
1026 $cache_id = 'bbp_get_forum_' . $forum_id . '_reply_id';
1027
1028 if ( !$reply_id = (int) wp_cache_get( $cache_id, 'bbpress' ) ) {
1029
1030 if ( empty( $topic_ids ) )
1031 $topic_ids = bbp_forum_query_topic_ids( $forum_id );
1032
1033 if ( !empty( $topic_ids ) && ( $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() ) ) ) )
1034 wp_cache_set( $cache_id, $reply_id, 'bbpress' );
1035 else
1036 wp_cache_set( $cache_id, '0', 'bbpress' );
1037 }
1038
1039 return apply_filters( 'bbp_get_forum_last_reply_id', (int) $reply_id, $forum_id );
1040 }
1041
1042 /** Listeners *****************************************************************/
1043
1044 /**
1045 * Check if it's a hidden forum or a topic or reply of a hidden forum and if
1046 * the user can't view it, then sets a 404
1047 *
1048 * @since bbPress (r2996)
1049 *
1050 * @uses current_user_can() To check if the current user can read private forums
1051 * @uses is_singular() To check if it's a singular page
1052 * @uses bbp_get_forum_post_type() To get the forum post type
1053 * @uses bbp_get_topic_post_type() To get the topic post type
1054 * @uses bbp_get_reply_post_type() TO get the reply post type
1055 * @uses bbp_get_topic_forum_id() To get the topic forum id
1056 * @uses bbp_get_reply_forum_id() To get the reply forum id
1057 * @uses bbp_is_forum_hidden() To check if the forum is hidden or not
1058 * @uses bbp_set_404() To set a 404 status
1059 */
1060 function bbp_forum_enforce_hidden() {
1061
1062 // Bail if not viewing a single item or if user has caps
1063 if ( !is_singular() || is_super_admin() || current_user_can( 'read_hidden_forums' ) )
1064 return;
1065
1066 global $wp_query;
1067
1068 // Define local variable
1069 $forum_id = 0;
1070
1071 // Check post type
1072 switch ( $wp_query->get( 'post_type' ) ) {
1073
1074 // Forum
1075 case bbp_get_forum_post_type() :
1076 $forum_id = bbp_get_forum_id( $wp_query->post->ID );
1077 break;
1078
1079 // Topic
1080 case bbp_get_topic_post_type() :
1081 $forum_id = bbp_get_topic_forum_id( $wp_query->post->ID );
1082 break;
1083
1084 // Reply
1085 case bbp_get_reply_post_type() :
1086 $forum_id = bbp_get_reply_forum_id( $wp_query->post->ID );
1087 break;
1088
1089 }
1090
1091 // If forum is explicitly hidden and user not capable, set 404
1092 if ( !empty( $forum_id ) && bbp_is_forum_hidden( $forum_id ) && !current_user_can( 'read_hidden_forums' ) )
1093 bbp_set_404();
1094 }
1095
1096 /**
1097 * Check if it's a private forum or a topic or reply of a private forum and if
1098 * the user can't view it, then sets a 404
1099 *
1100 * @since bbPress (r2996)
1101 *
1102 * @uses current_user_can() To check if the current user can read private forums
1103 * @uses is_singular() To check if it's a singular page
1104 * @uses bbp_get_forum_post_type() To get the forum post type
1105 * @uses bbp_get_topic_post_type() To get the topic post type
1106 * @uses bbp_get_reply_post_type() TO get the reply post type
1107 * @uses bbp_get_topic_forum_id() To get the topic forum id
1108 * @uses bbp_get_reply_forum_id() To get the reply forum id
1109 * @uses bbp_is_forum_private() To check if the forum is private or not
1110 * @uses bbp_set_404() To set a 404 status
1111 */
1112 function bbp_forum_enforce_private() {
1113
1114 // Bail if not viewing a single item or if user has caps
1115 if ( !is_singular() || is_super_admin() || current_user_can( 'read_private_forums' ) )
1116 return;
1117
1118 global $wp_query;
1119
1120 // Define local variable
1121 $forum_id = 0;
1122
1123 // Check post type
1124 switch ( $wp_query->get( 'post_type' ) ) {
1125
1126 // Forum
1127 case bbp_get_forum_post_type() :
1128 $forum_id = bbp_get_forum_id( $wp_query->post->ID );
1129 break;
1130
1131 // Topic
1132 case bbp_get_topic_post_type() :
1133 $forum_id = bbp_get_topic_forum_id( $wp_query->post->ID );
1134 break;
1135
1136 // Reply
1137 case bbp_get_reply_post_type() :
1138 $forum_id = bbp_get_reply_forum_id( $wp_query->post->ID );
1139 break;
1140
1141 }
1142
1143 // If forum is explicitly hidden and user not capable, set 404
1144 if ( !empty( $forum_id ) && bbp_is_forum_private( $forum_id ) && !current_user_can( 'read_private_forums' ) )
1145 bbp_set_404();
1146 }
1147
1148 ?>
1149