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

995 lines 31.8 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' => 'publish',
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 ( 'publish' != $current_visibility ) {
211
212 // Remove from _bbp_private_forums site option
213 if ( 'private' == $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 ( 'hidden' == $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' => 'publish' ), array( 'ID' => $forum_id ) );
253 wp_transition_post_status( 'publish', $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 ( 'private' != $current_visibility ) {
278
279 // Remove from _bbp_hidden_forums site option
280 if ( 'hidden' == $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' => 'private' ), array( 'ID' => $forum_id ) );
306 wp_transition_post_status( 'private', $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 ( 'hidden' != $current_visibility ) {
331
332 // Remove from _bbp_private_forums site option
333 if ( 'private' == $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 $bbp, $wpdb;
358 $wpdb->update( $wpdb->posts, array( 'post_status' => 'hidden' ), array( 'ID' => $forum_id ) );
359 wp_transition_post_status( $bbp->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 // Do some calculation if not manually set
390 if ( empty( $topic_id ) ) {
391
392 // Loop through children and add together forum reply counts
393 if ( $children = bbp_forum_query_subforum_ids( $forum_id ) )
394 foreach ( (array) $children as $child )
395 $children_last_topic = bbp_update_forum_last_topic_id ( $child );
396
397 // Setup recent topic query vars
398 $post_vars = array(
399 'post_parent' => $forum_id,
400 'post_type' => bbp_get_topic_post_type(),
401 'meta_key' => '_bbp_last_active_time',
402 'orderby' => 'meta_value',
403 'numberposts' => 1
404 );
405
406 // Get the most recent topic in this forum_id
407 if ( $recent_topic = get_posts( $post_vars ) )
408 $topic_id = $recent_topic[0]->ID;
409 }
410
411 // If child forums have higher id, use that instead
412 if ( !empty( $children ) && ( $children_last_topic > $topic_id ) )
413 $topic_id = $children_last_topic;
414
415 // Update the last topic id
416 update_post_meta( $forum_id, '_bbp_last_topic_id', (int) $topic_id );
417
418 return apply_filters( 'bbp_update_forum_last_topic_id', (int) $topic_id, $forum_id );
419 }
420
421 /**
422 * Update the forum last reply id
423 *
424 * @since bbPress (r2625)
425 *
426 * @param int $forum_id Optional. Forum id
427 * @param int $reply_id Optional. Reply id
428 * @uses bbp_get_forum_id() To get the forum id
429 * @uses bbp_forum_query_subforum_ids() To get the subforum ids
430 * @uses bbp_update_forum_last_reply_id() To update the last reply id of child
431 * forums
432 * @uses bbp_forum_query_topic_ids() To get the topic ids in the forum
433 * @uses bbp_forum_query_last_reply_id() To get the forum's last reply id
434 * @uses update_post_meta() To update the forum's last active id meta
435 * @uses apply_filters() Calls 'bbp_update_forum_last_reply_id' with the last
436 * reply id and forum id
437 * @return bool True on success, false on failure
438 */
439 function bbp_update_forum_last_reply_id( $forum_id = 0, $reply_id = 0 ) {
440 $forum_id = bbp_get_forum_id( $forum_id );
441
442 // Do some calculation if not manually set
443 if ( empty( $reply_id ) ) {
444
445 // Loop through children and get the most recent reply id
446 if ( $children = bbp_forum_query_subforum_ids( $forum_id ) )
447 foreach ( (array) $children as $child )
448 $children_last_reply = bbp_update_forum_last_reply_id ( $child );
449
450 // If this forum has topics...
451 if ( $topic_ids = bbp_forum_query_topic_ids( $forum_id ) ) {
452
453 // ...get the most recent reply from those topics...
454 $reply_id = bbp_forum_query_last_reply_id( $forum_id, $topic_ids );
455
456 // ...and compare it to the most recent topic id...
457 $reply_id = ( $reply_id > max( $topic_ids ) ) ? $reply_id : max( $topic_ids );
458 }
459 }
460
461 // If child forums have higher ID, check for newer reply id
462 if ( !empty( $children ) && ( (int) $children_last_reply > (int) $reply_id ) )
463 $reply_id = $children_last_reply;
464
465 // Update the last reply id with what was passed
466 update_post_meta( $forum_id, '_bbp_last_reply_id', (int) $reply_id );
467
468 return apply_filters( 'bbp_update_forum_last_reply_id', (int) $reply_id, $forum_id );
469 }
470
471 /**
472 * Update the forum last active post id
473 *
474 * @since bbPress (r2860)
475 *
476 * @param int $forum_id Optional. Forum id
477 * @param int $active_id Optional. Active post id
478 * @uses bbp_get_forum_id() To get the forum id
479 * @uses bbp_forum_query_subforum_ids() To get the subforum ids
480 * @uses bbp_update_forum_last_active_id() To update the last active id of
481 * child forums
482 * @uses bbp_forum_query_topic_ids() To get the topic ids in the forum
483 * @uses bbp_forum_query_last_reply_id() To get the forum's last reply id
484 * @uses update_post_meta() To update the forum's last active id meta
485 * @uses apply_filters() Calls 'bbp_update_forum_last_active_id' with the last
486 * active post id and forum id
487 * @return bool True on success, false on failure
488 */
489 function bbp_update_forum_last_active_id( $forum_id = 0, $active_id = 0 ) {
490 $forum_id = bbp_get_forum_id( $forum_id );
491
492 // Do some calculation if not manually set
493 if ( empty( $active_id ) ) {
494
495 // Loop through children and add together forum reply counts
496 if ( $children = bbp_forum_query_subforum_ids( $forum_id ) )
497 foreach ( (array) $children as $child )
498 $children_last_active = bbp_update_forum_last_active_id ( $child, $active_id );
499
500 // Don't count replies if the forum is a category
501 if ( $topic_ids = bbp_forum_query_topic_ids( $forum_id ) ) {
502 $active_id = bbp_forum_query_last_reply_id( $forum_id, $topic_ids );
503 $active_id = $active_id > max( $topic_ids ) ? $active_id : max( $topic_ids );
504
505 // Forum has no topics
506 } else {
507 $active_id = 0;
508 }
509 }
510
511 // If child forums have higher id, use that instead
512 if ( !empty( $children ) && ( $children_last_active > $active_id ) )
513 $active_id = $children_last_active;
514
515 update_post_meta( $forum_id, '_bbp_last_active_id', (int) $active_id );
516
517 return apply_filters( 'bbp_update_forum_last_active_id', (int) $active_id, $forum_id );
518 }
519
520 /**
521 * Update the forums last active date/time (aka freshness)
522 *
523 * @since bbPress (r2680)
524 *
525 * @param int $forum_id Optional. Topic id
526 * @param string $new_time Optional. New time in mysql format
527 * @uses bbp_get_forum_id() To get the forum id
528 * @uses bbp_get_forum_last_active_id() To get the forum's last post id
529 * @uses get_post_field() To get the post date of the forum's last post
530 * @uses update_post_meta() To update the forum last active time
531 * @uses apply_filters() Calls 'bbp_update_forum_last_active' with the new time
532 * and forum id
533 * @return bool True on success, false on failure
534 */
535 function bbp_update_forum_last_active_time( $forum_id = 0, $new_time = '' ) {
536 $forum_id = bbp_get_forum_id( $forum_id );
537
538 // Check time and use current if empty
539 if ( empty( $new_time ) )
540 $new_time = get_post_field( 'post_date', bbp_get_forum_last_active_id( $forum_id ) );
541
542 update_post_meta( $forum_id, '_bbp_last_active_time', $new_time );
543
544 return apply_filters( 'bbp_update_forum_last_active', $new_time, $forum_id );
545 }
546
547 /**
548 * Update the forum sub-forum count
549 *
550 * @since bbPress (r2625)
551 *
552 * @param int $forum_id Optional. Forum id
553 * @uses bbp_get_forum_id() To get the forum id
554 * @return bool True on success, false on failure
555 */
556 function bbp_update_forum_subforum_count( $forum_id = 0, $subforums = 0 ) {
557 $forum_id = bbp_get_forum_id( $forum_id );
558
559 if ( empty( $subforums ) )
560 $subforums = count( bbp_forum_query_subforum_ids( $forum_id ) );
561
562 update_post_meta( $forum_id, '_bbp_forum_subforum_count', (int) $subforums );
563
564 return apply_filters( 'bbp_update_forum_subforum_count', (int) $subforums, $forum_id );
565 }
566
567 /**
568 * Adjust the total topic count of a forum
569 *
570 * @since bbPress (r2464)
571 *
572 * @param int $forum_id Optional. Forum id or topic id. It is checked whether it
573 * is a topic or a forum. If it's a topic, its parent,
574 * i.e. the forum is automatically retrieved.
575 * @param bool $total_count Optional. To return the total count or normal
576 * count?
577 * @uses bbp_get_forum_id() To get the forum id
578 * @uses bbp_forum_query_subforum_ids() To get the subforum ids
579 * @uses bbp_update_forum_topic_count() To update the forum topic count
580 * @uses bbp_forum_query_topic_ids() To get the forum topic ids
581 * @uses update_post_meta() To update the forum's topic count meta
582 * @uses apply_filters() Calls 'bbp_update_forum_topic_count' with the topic
583 * count and forum id
584 * @return int Forum topic count
585 */
586 function bbp_update_forum_topic_count( $forum_id = 0 ) {
587 $forum_id = bbp_get_forum_id( $forum_id );
588 $children_topic_count = 0;
589
590 // Loop through subforums and add together forum topic counts
591 if ( $children = bbp_forum_query_subforum_ids( $forum_id ) )
592 foreach ( (array) $children as $child )
593 $children_topic_count += bbp_update_forum_topic_count( $child );
594
595 // Get total topics for this forum
596 $topics = (int) count( bbp_forum_query_topic_ids( $forum_id ) );
597
598 // Calculate total topics in this forum
599 $total_topics = $topics + $children_topic_count;
600
601 // Update the count
602 update_post_meta( $forum_id, '_bbp_topic_count', (int) $topics );
603 update_post_meta( $forum_id, '_bbp_total_topic_count', (int) $total_topics );
604
605 return apply_filters( 'bbp_update_forum_topic_count', (int) $total_topics, $forum_id );
606 }
607
608 /**
609 * Adjust the total hidden topic count of a forum (hidden includes trashed and spammed topics)
610 *
611 * @since bbPress (r2888)
612 *
613 * @param int $forum_id Optional. Topic id to update
614 * @param int $topic_count Optional. Set the topic count manually
615 * @uses bbp_is_topic() To check if the supplied id is a topic
616 * @uses bbp_get_topic_id() To get the topic id
617 * @uses bbp_get_topic_forum_id() To get the topic forum id
618 * @uses bbp_get_forum_id() To get the forum id
619 * @uses wpdb::prepare() To prepare our sql query
620 * @uses wpdb::get_col() To execute our query and get the column back
621 * @uses update_post_meta() To update the forum hidden topic count meta
622 * @uses apply_filters() Calls 'bbp_update_forum_topic_count_hidden' with the
623 * hidden topic count and forum id
624 * @return int Topic hidden topic count
625 */
626 function bbp_update_forum_topic_count_hidden( $forum_id = 0, $topic_count = 0 ) {
627 global $wpdb, $bbp;
628
629 // If topic_id was passed as $forum_id, then get its forum
630 if ( bbp_is_topic( $forum_id ) ) {
631 $topic_id = bbp_get_topic_id( $forum_id );
632 $forum_id = bbp_get_topic_forum_id( $topic_id );
633
634 // $forum_id is not a topic_id, so validate and proceed
635 } else {
636 $forum_id = bbp_get_forum_id( $forum_id );
637 }
638
639 // Can't update what isn't there
640 if ( !empty( $forum_id ) ) {
641
642 // Get topics of forum
643 if ( empty( $topic_count ) )
644 $topic_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_parent = %d AND post_status IN ( '" . join( '\',\'', array( $bbp->trash_status_id, $bbp->spam_status_id ) ) . "') AND post_type = '%s';", $forum_id, bbp_get_topic_post_type() ) );
645
646 // Update the count
647 update_post_meta( $forum_id, '_bbp_topic_count_hidden', (int) $topic_count );
648 }
649
650 return apply_filters( 'bbp_update_forum_topic_count_hidden', (int) $topic_count, $forum_id );
651 }
652
653 /**
654 * Adjust the total reply count of a forum
655 *
656 * @since bbPress (r2464)
657 *
658 * @param int $forum_id Optional. Forum id or topic id. It is checked whether it
659 * is a topic or a forum. If it's a topic, its parent,
660 * i.e. the forum is automatically retrieved.
661 * @param bool $total_count Optional. To return the total count or normal
662 * count?
663 * @uses bbp_get_forum_id() To get the forum id
664 * @uses bbp_forum_query_subforum_ids() To get the subforum ids
665 * @uses bbp_update_forum_reply_count() To update the forum reply count
666 * @uses bbp_forum_query_topic_ids() To get the forum topic ids
667 * @uses wpdb::prepare() To prepare the sql statement
668 * @uses wpdb::get_var() To execute the query and get the var back
669 * @uses update_post_meta() To update the forum's reply count meta
670 * @uses apply_filters() Calls 'bbp_update_forum_topic_count' with the reply
671 * count and forum id
672 * @return int Forum reply count
673 */
674 function bbp_update_forum_reply_count( $forum_id = 0 ) {
675 global $wpdb, $bbp;
676
677 $forum_id = bbp_get_forum_id( $forum_id );
678 $children_reply_count = 0;
679
680 // Loop through children and add together forum reply counts
681 if ( $children = bbp_forum_query_subforum_ids( $forum_id ) )
682 foreach ( (array) $children as $child )
683 $children_reply_count += bbp_update_forum_reply_count( $child );
684
685 // Don't count replies if the forum is a category
686 if ( $topic_ids = bbp_forum_query_topic_ids( $forum_id ) )
687 $reply_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_parent IN ( " . join( ',', $topic_ids ) . " ) AND post_status = 'publish' AND post_type = '%s';", bbp_get_reply_post_type() ) );
688 else
689 $reply_count = 0;
690
691 // Calculate total replies in this forum
692 $total_replies = (int) $reply_count + $children_reply_count;
693
694 // Update the count
695 update_post_meta( $forum_id, '_bbp_reply_count', $reply_count );
696 update_post_meta( $forum_id, '_bbp_total_reply_count', $total_replies );
697
698 return apply_filters( 'bbp_update_forum_reply_count', $total_replies, $forum_id );
699 }
700
701 /**
702 * Updates the counts of a forum.
703 *
704 * This calls a few internal functions that all run manual queries against the
705 * database to get their results. As such, this function can be costly to run
706 * but is necessary to keep everything accurate.
707 *
708 * @since bbPress (r2908)
709 *
710 * @param mixed $args Supports these arguments:
711 * - forum_id: Forum id
712 * - last_topic_id: Last topic id
713 * - last_reply_id: Last reply id
714 * - last_active_id: Last active post id
715 * - last_active_time: last active time
716 * @uses bbp_update_forum_last_topic_id() To update the forum last topic id
717 * @uses bbp_update_forum_last_reply_id() To update the forum last reply id
718 * @uses bbp_update_forum_last_active_id() To update the last active post id
719 * @uses get_post_field() To get the post date of the last active id
720 * @uses bbp_update_forum_last_active_time() To update the last active time
721 * @uses bbp_update_forum_subforum_count() To update the subforum count
722 * @uses bbp_update_forum_topic_count() To update the forum topic count
723 * @uses bbp_update_forum_reply_count() To update the forum reply count
724 * @uses bbp_update_forum_topic_count_hidden() To update the hidden topic count
725 */
726 function bbp_update_forum( $args = '' ) {
727 $defaults = array(
728 'forum_id' => 0,
729 'post_parent' => 0,
730 'last_topic_id' => 0,
731 'last_reply_id' => 0,
732 'last_active_id' => 0,
733 'last_active_time' => 0,
734 );
735
736 $r = wp_parse_args( $args, $defaults );
737 extract( $r );
738
739 // Last topic and reply ID's
740 bbp_update_forum_last_topic_id( $forum_id, $last_topic_id );
741 bbp_update_forum_last_reply_id( $forum_id, $last_reply_id );
742
743 // Active dance
744 $last_active_id = bbp_update_forum_last_active_id( $forum_id, $last_active_id );
745
746 // If no active time was passed, get it from the last_active_id
747 if ( empty( $last_active_time ) )
748 $last_active_time = get_post_field( 'post_date', $last_active_id );
749
750 bbp_update_forum_last_active_time( $forum_id, $last_active_time );
751
752 // Counts
753 bbp_update_forum_subforum_count ( $forum_id );
754 bbp_update_forum_reply_count ( $forum_id );
755 bbp_update_forum_topic_count ( $forum_id );
756 bbp_update_forum_topic_count_hidden( $forum_id );
757
758 // Update the parent forum if one was passed
759 if ( !empty( $post_parent ) && is_numeric( $post_parent ) ) {
760 bbp_update_forum( array(
761 'forum_id' => $post_parent,
762 'post_parent' => get_post_field( 'post_parent', $post_parent )
763 ) );
764 }
765 }
766
767 /** Queries *******************************************************************/
768
769 /**
770 * Returns the hidden forum ids
771 *
772 * Only hidden forum ids are returned. Public and private ids are not.
773 *
774 * @since bbPress (r3007)
775 *
776 * @uses get_option() Returns the unserialized array of hidden forum ids
777 * @uses apply_filters() Calls 'bbp_forum_query_topic_ids' with the topic ids
778 * and forum id
779 */
780 function bbp_get_hidden_forum_ids() {
781 $forum_ids = get_option( '_bbp_hidden_forums', array() );
782
783 return apply_filters( 'bbp_get_hidden_forum_ids', (array) $forum_ids );
784 }
785
786 /**
787 * Returns the private forum ids
788 *
789 * Only private forum ids are returned. Public and hidden ids are not.
790 *
791 * @since bbPress (r3007)
792 *
793 * @uses get_option() Returns the unserialized array of private forum ids
794 * @uses apply_filters() Calls 'bbp_forum_query_topic_ids' with the topic ids
795 * and forum id
796 */
797 function bbp_get_private_forum_ids() {
798 $forum_ids = get_option( '_bbp_private_forums', array() );
799
800 return apply_filters( 'bbp_get_private_forum_ids', (array) $forum_ids );
801 }
802
803 /**
804 * Returns a meta_query that either includes or excludes hidden forum IDs
805 * from a query.
806 *
807 * @since bbPress (r3291)
808 *
809 * @param string Optional. The type of value to return. (string|array|meta_query)
810 *
811 * @uses is_super_admin()
812 * @uses bbp_is_user_home()
813 * @uses bbp_get_hidden_forum_ids()
814 * @uses bbp_get_private_forum_ids()
815 * @uses apply_filters()
816 */
817 function bbp_exclude_forum_ids( $type = 'string' ) {
818
819 // Setup arrays
820 $retval = $private = $hidden = $meta_query = $forum_ids = array();
821
822 // Exclude for everyone but super admins
823 if ( !is_super_admin() ) {
824
825 // Private forums
826 if ( !current_user_can( 'read_private_forums' ) )
827 $private = bbp_get_private_forum_ids();
828
829 // Hidden forums
830 if ( !current_user_can( 'read_hidden_forums' ) )
831 $hidden = bbp_get_hidden_forum_ids();
832
833 // Merge private and hidden forums together
834 $forum_ids = (array) array_filter( array_merge( $private, $hidden ) );
835
836 // There are forums that need to be excluded
837 if ( !empty( $forum_ids ) ) {
838
839 switch ( $type ) {
840
841 // Separate forum ID's into a comma separated string
842 case 'string' :
843 $retval = implode( ',', $forum_ids );
844 break;
845
846 // Use forum_ids array
847 case 'array' :
848 $retval = $forum_ids;
849 break;
850
851 // Build a meta_query
852 case 'meta_query' :
853 $retval = array(
854 'key' => '_bbp_forum_id',
855 'value' => implode( ',', $forum_ids ),
856 'compare' => ( 1 < count( $forum_ids ) ) ? 'NOT IN' : '!='
857 );
858 break;
859 }
860 }
861 }
862
863 // Filter and return the results
864 return apply_filters( 'bbp_exclude_forum_ids', $retval, $forum_ids, $type );
865 }
866
867 /**
868 * Returns the forum's topic ids
869 *
870 * Only topics with published and closed statuses are returned
871 *
872 * @since bbPress (r2908)
873 *
874 * @param int $forum_id Forum id
875 * @uses bbp_get_topic_post_type() To get the topic post type
876 * @uses bbp_get_public_child_ids() To get the topic ids
877 * @uses apply_filters() Calls 'bbp_forum_query_topic_ids' with the topic ids
878 * and forum id
879 */
880 function bbp_forum_query_topic_ids( $forum_id ) {
881 global $bbp;
882
883 $topic_ids = bbp_get_public_child_ids( $forum_id, bbp_get_topic_post_type() );
884
885 return apply_filters( 'bbp_forum_query_topic_ids', $topic_ids, $forum_id );
886 }
887
888 /**
889 * Returns the forum's subforum ids
890 *
891 * Only forums with published status are returned
892 *
893 * @since bbPress (r2908)
894 *
895 * @param int $forum_id Forum id
896 * @uses bbp_get_forum_post_type() To get the forum post type
897 * @uses bbp_get_public_child_ids() To get the forum ids
898 * @uses apply_filters() Calls 'bbp_forum_query_subforum_ids' with the subforum
899 * ids and forum id
900 */
901 function bbp_forum_query_subforum_ids( $forum_id ) {
902 global $bbp, $wpdb;
903
904 $subforum_ids = bbp_get_public_child_ids( $forum_id, bbp_get_forum_post_type() );
905
906 return apply_filters( 'bbp_get_forum_subforum_ids', $subforum_ids, $forum_id );
907 }
908
909 /**
910 * Returns the forum's last reply id
911 *
912 * @since bbPress (r2908)
913 *
914 * @param int $forum_id Forum id
915 * @param int $topic_ids Optional. Topic ids
916 * @uses wp_cache_get() To check for cache and retrieve it
917 * @uses bbp_forum_query_topic_ids() To get the forum's topic ids
918 * @uses wpdb::prepare() To prepare the query
919 * @uses wpdb::get_var() To execute the query and get the var back
920 * @uses bbp_get_reply_post_type() To get the reply post type
921 * @uses wp_cache_set() To set the cache for future use
922 * @uses apply_filters() Calls 'bbp_forum_query_last_reply_id' with the reply id
923 * and forum id
924 */
925 function bbp_forum_query_last_reply_id( $forum_id, $topic_ids = 0 ) {
926 global $bbp, $wpdb;
927
928 $cache_id = 'bbp_get_forum_' . $forum_id . '_reply_id';
929
930 if ( !$reply_id = (int) wp_cache_get( $cache_id, 'bbpress' ) ) {
931
932 if ( empty( $topic_ids ) )
933 $topic_ids = bbp_forum_query_topic_ids( $forum_id );
934
935 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 = 'publish' AND post_type = '%s' ORDER BY ID DESC LIMIT 1;", bbp_get_reply_post_type() ) ) ) )
936 wp_cache_set( $cache_id, $reply_id, 'bbpress' );
937 else
938 wp_cache_set( $cache_id, '0', 'bbpress' );
939 }
940
941 return apply_filters( 'bbp_get_forum_last_reply_id', (int) $reply_id, $forum_id );
942 }
943
944 /** Listeners *****************************************************************/
945
946 /**
947 * Check if it's a private forum or a topic or reply of a private forum and if
948 * the user can't view it, then sets a 404
949 *
950 * @since bbPress (r2996)
951 *
952 * @uses current_user_can() To check if the current user can read private forums
953 * @uses is_singular() To check if it's a singular page
954 * @uses bbp_get_forum_post_type() To get the forum post type
955 * @uses bbp_get_topic_post_type() To get the topic post type
956 * @uses bbp_get_reply_post_type() TO get the reply post type
957 * @uses bbp_get_topic_forum_id() To get the topic forum id
958 * @uses bbp_get_reply_forum_id() To get the reply forum id
959 * @uses bbp_is_forum_private() To check if the forum is private or not
960 * @uses bbp_set_404() To set a 404 status
961 */
962 function bbp_forum_visibility_check() {
963 global $wp_query;
964
965 // Bail if not viewing a single item or if user has caps
966 if ( !is_singular() || is_super_admin() || ( current_user_can( 'read_private_forums' ) && current_user_can( 'read_hidden_forums' ) ) )
967 return;
968
969 // Check post type
970 switch ( $wp_query->get( 'post_type' ) ) {
971
972 // Forum
973 case bbp_get_forum_post_type() :
974 $forum_id = bbp_get_forum_id( $wp_query->post->ID );
975 break;
976
977 // Topic
978 case bbp_get_topic_post_type() :
979 $forum_id = bbp_get_topic_forum_id( $wp_query->post->ID );
980 break;
981
982 // Reply
983 case bbp_get_reply_post_type() :
984 $forum_id = bbp_get_reply_forum_id( $wp_query->post->ID );
985 break;
986
987 }
988
989 // If forum is explicitly hidden and user not capable, set 404
990 if ( !empty( $forum_id ) && bbp_is_forum_hidden( $forum_id ) && !current_user_can( 'read_hidden_forums' ) )
991 bbp_set_404();
992 }
993
994 ?>
995