PluginProbe
bbPress / 2.0-rc-4
bbPress v2.0-rc-4
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-topic-functions.php

bbp-topic-functions.php in bbPress 2.0-rc-4, at bbp-includes/bbp-topic-functions.php

2,885 lines 101.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * bbPress Topic 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 topic to function properly.
18 *
19 * @since bbPress (r3349)
20 *
21 * @uses wp_parse_args()
22 * @uses bbp_get_topic_post_type()
23 * @uses wp_insert_post()
24 * @uses update_post_meta()
25 *
26 * @param array $topic_data Forum post data
27 * @param arrap $topic_meta Forum meta data
28 */
29 function bbp_insert_topic( $topic_data = array(), $topic_meta = array() ) {
30
31 // Forum
32 $default_topic = array(
33 'post_parent' => 0, // forum ID
34 'post_status' => 'publish',
35 'post_type' => bbp_get_topic_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 $topic_data = wp_parse_args( $topic_data, $default_topic );
45
46 // Insert topic
47 $topic_id = wp_insert_post( $topic_data );
48
49 // Bail if no topic was added
50 if ( empty( $topic_id ) )
51 return false;
52
53 // Forum meta
54 $default_meta = array(
55 'author_ip' => bbp_current_author_ip(),
56 'forum_id' => 0,
57 'topic_id' => $topic_id,
58 'voice_count' => 1,
59 'reply_count' => 0,
60 'reply_count_hidden' => 0,
61 'last_reply_id' => 0,
62 'last_active_id' => $topic_id,
63 'last_active_time' => get_post_field( 'post_date', $topic_id, 'db' ),
64 );
65
66 // Parse args
67 $topic_meta = wp_parse_args( $topic_meta, $default_meta );
68
69 // Insert topic meta
70 foreach ( $topic_meta as $meta_key => $meta_value )
71 update_post_meta( $topic_id, '_bbp_' . $meta_key, $meta_value );
72
73 // Update the forum
74 $forum_id = bbp_get_topic_forum_id( $topic_id );
75 if ( !empty( $forum_id ) )
76 bbp_update_forum( $forum_id );
77
78 // Return new topic ID
79 return $topic_id;
80 }
81
82 /** Post Form Handlers ********************************************************/
83
84 /**
85 * Handles the front end topic submission
86 *
87 * @uses bbPress:errors::add() To log various error messages
88 * @uses check_admin_referer() To verify the nonce and check the referer
89 * @uses bbp_is_anonymous() To check if an anonymous post is being made
90 * @uses current_user_can() To check if the current user can publish topic
91 * @uses bbp_get_current_user_id() To get the current user id
92 * @uses bbp_filter_anonymous_post_data() To filter anonymous data
93 * @uses bbp_set_current_anonymous_user_data() To set the anonymous user cookies
94 * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
95 * @uses esc_attr() For sanitization
96 * @uses bbp_is_forum_category() To check if the forum is a category
97 * @uses bbp_is_forum_closed() To check if the forum is closed
98 * @uses bbp_is_forum_private() To check if the forum is private
99 * @uses bbp_check_for_flood() To check for flooding
100 * @uses bbp_check_for_duplicate() To check for duplicates
101 * @uses bbp_get_topic_post_type() To get the topic post type
102 * @uses remove_filter() To remove 'wp_filter_kses' filters if needed
103 * @uses apply_filters() Calls 'bbp_new_topic_pre_title' with the content
104 * @uses apply_filters() Calls 'bbp_new_topic_pre_content' with the content
105 * @uses bbPress::errors::get_error_codes() To get the {@link WP_Error} errors
106 * @uses wp_insert_post() To insert the topic
107 * @uses do_action() Calls 'bbp_new_topic' with the topic id, forum id,
108 * anonymous data and reply author
109 * @uses bbp_stick_topic() To stick or super stick the topic
110 * @uses bbp_unstick_topic() To unstick the topic
111 * @uses bbp_get_topic_permalink() To get the topic permalink
112 * @uses wp_safe_redirect() To redirect to the topic link
113 * @uses bbPress::errors::get_error_messages() To get the {@link WP_Error} error
114 * messages
115 */
116 function bbp_new_topic_handler() {
117
118 // Bail if not a POST action
119 if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
120 return;
121
122 // Bail if action is not bbp-new-topic
123 if ( empty( $_POST['action'] ) || ( 'bbp-new-topic' !== $_POST['action'] ) )
124 return;
125
126 global $bbp;
127
128 // Nonce check
129 check_admin_referer( 'bbp-new-topic' );
130
131 // Define local variable(s)
132 $view_all = false;
133 $forum_id = $topic_author = $anonymous_data = 0;
134 $topic_title = $topic_content = '';
135 $terms = array( bbp_get_topic_tag_tax_id() => array() );
136
137 /** Topic Author **********************************************************/
138
139 // User is anonymous
140 if ( bbp_is_anonymous() ) {
141
142 // Filter anonymous data
143 $anonymous_data = bbp_filter_anonymous_post_data();
144
145 // Anonymous data checks out, so set cookies, etc...
146 if ( !empty( $anonymous_data ) && is_array( $anonymous_data ) ) {
147 bbp_set_current_anonymous_user_data( $anonymous_data );
148 }
149
150 // User is logged in
151 } else {
152
153 // User cannot create topics
154 if ( !current_user_can( 'publish_topics' ) ) {
155 bbp_add_error( 'bbp_topic_permissions', __( '<strong>ERROR</strong>: You do not have permission to create new topics.', 'bbpress' ) );
156 }
157
158 // Topic author is current user
159 $topic_author = bbp_get_current_user_id();
160
161 }
162
163 // Remove wp_filter_kses filters from title and content for capable users and if the nonce is verified
164 if ( current_user_can( 'unfiltered_html' ) && !empty( $_POST['_bbp_unfiltered_html_topic'] ) && wp_create_nonce( 'bbp-unfiltered-html-topic_new' ) == $_POST['_bbp_unfiltered_html_topic'] ) {
165 remove_filter( 'bbp_new_topic_pre_title', 'wp_filter_kses' );
166 remove_filter( 'bbp_new_topic_pre_content', 'wp_filter_kses' );
167 }
168
169 /** Topic Title ***********************************************************/
170
171 if ( !empty( $_POST['bbp_topic_title'] ) )
172 $topic_title = esc_attr( strip_tags( $_POST['bbp_topic_title'] ) );
173
174 // Filter and sanitize
175 $topic_title = apply_filters( 'bbp_new_topic_pre_title', $topic_title );
176
177 // No topic title
178 if ( empty( $topic_title ) )
179 bbp_add_error( 'bbp_topic_title', __( '<strong>ERROR</strong>: Your topic needs a title.', 'bbpress' ) );
180
181 /** Topic Content *********************************************************/
182
183 if ( !empty( $_POST['bbp_topic_content'] ) )
184 $topic_content = $_POST['bbp_topic_content'];
185
186 // Filter and sanitize
187 $topic_content = apply_filters( 'bbp_new_topic_pre_content', $topic_content );
188
189 // No topic content
190 if ( empty( $topic_content ) )
191 bbp_add_error( 'bbp_topic_content', __( '<strong>ERROR</strong>: Your topic cannot be empty.', 'bbpress' ) );
192
193 /** Topic Forum ***********************************************************/
194
195 // Forum id was not passed
196 if ( empty( $_POST['bbp_forum_id'] ) )
197 bbp_add_error( 'bbp_topic_forum_id', __( '<strong>ERROR</strong>: Forum ID is missing.', 'bbpress' ) );
198
199 // Forum id was passed
200 elseif ( is_numeric( $_POST['bbp_forum_id'] ) )
201 $forum_id = (int) $_POST['bbp_forum_id'];
202
203 // Forum exists
204 if ( !empty( $forum_id ) ) {
205
206 // Forum is a category
207 if ( bbp_is_forum_category( $forum_id ) )
208 bbp_add_error( 'bbp_edit_topic_forum_category', __( '<strong>ERROR</strong>: This forum is a category. No topics can be created in this forum.', 'bbpress' ) );
209
210 // Forum is closed and user cannot access
211 if ( bbp_is_forum_closed( $forum_id ) && !current_user_can( 'edit_forum', $forum_id ) )
212 bbp_add_error( 'bbp_edit_topic_forum_closed', __( '<strong>ERROR</strong>: This forum has been closed to new topics.', 'bbpress' ) );
213
214 // Forum is private and user cannot access
215 if ( bbp_is_forum_private( $forum_id ) && !current_user_can( 'read_private_forums' ) )
216 bbp_add_error( 'bbp_edit_topic_forum_private', __( '<strong>ERROR</strong>: This forum is private and you do not have the capability to read or create new topics in it.', 'bbpress' ) );
217
218 // Forum is hidden and user cannot access
219 if ( bbp_is_forum_hidden( $forum_id ) && !current_user_can( 'read_hidden_forums' ) )
220 bbp_add_error( 'bbp_edit_topic_forum_hidden', __( '<strong>ERROR</strong>: This forum is hidden and you do not have the capability to read or create new topics in it.', 'bbpress' ) );
221 }
222
223 /** Topic Flooding ********************************************************/
224
225 if ( !bbp_check_for_flood( $anonymous_data, $topic_author ) )
226 bbp_add_error( 'bbp_topic_flood', __( '<strong>ERROR</strong>: Slow down; you move too fast.', 'bbpress' ) );
227
228 /** Topic Duplicate *******************************************************/
229
230 if ( !bbp_check_for_duplicate( array( 'post_type' => bbp_get_topic_post_type(), 'post_author' => $topic_author, 'post_content' => $topic_content, 'anonymous_data' => $anonymous_data ) ) )
231 bbp_add_error( 'bbp_topic_duplicate', __( '<strong>ERROR</strong>: Duplicate topic detected; it looks as though you&#8217;ve already said that!', 'bbpress' ) );
232
233 /** topic Blacklist *******************************************************/
234
235 if ( !bbp_check_for_blacklist( $anonymous_data, $topic_author, $topic_title, $topic_content ) )
236 bbp_add_error( 'bbp_topic_blacklist', __( '<strong>ERROR</strong>: Your topic cannot be created at this time.', 'bbpress' ) );
237
238 /** Topic Tags ************************************************************/
239
240 if ( !empty( $_POST['bbp_topic_tags'] ) ) {
241
242 // Escape tag input
243 $terms = esc_attr( strip_tags( $_POST['bbp_topic_tags'] ) );
244
245 // Explode by comma
246 if ( strstr( $terms, ',' ) )
247 $terms = explode( ',', $terms );
248
249 // Add topic tag ID as main key
250 $terms = array( bbp_get_topic_tag_tax_id() => $terms );
251 }
252
253 /** Additional Actions (Before Save) **************************************/
254
255 do_action( 'bbp_new_topic_pre_extras' );
256
257 /** No Errors *************************************************************/
258
259 if ( !bbp_has_errors() ) {
260
261 /** Create new topic **************************************************/
262
263 // Add the content of the form to $post as an array
264 $topic_data = array(
265 'post_author' => $topic_author,
266 'post_title' => $topic_title,
267 'post_content' => $topic_content,
268 'post_parent' => $forum_id,
269 'tax_input' => $terms,
270 'post_status' => 'publish',
271 'post_type' => bbp_get_topic_post_type()
272 );
273
274 // Just in time manipulation of topic data before being created
275 $topic_data = apply_filters( 'bbp_new_topic_pre_insert', $topic_data );
276
277 // Insert topic
278 $topic_id = wp_insert_post( $topic_data );
279
280 /** No Errors *********************************************************/
281
282 if ( !empty( $topic_id ) && !is_wp_error( $topic_id ) ) {
283
284 /** Stickies ******************************************************/
285
286 if ( !empty( $_POST['bbp_stick_topic'] ) && in_array( $_POST['bbp_stick_topic'], array( 'stick', 'super', 'unstick' ) ) ) {
287
288 // What's the haps?
289 switch ( $_POST['bbp_stick_topic'] ) {
290
291 // Sticky in this forum
292 case 'stick' :
293 bbp_stick_topic( $topic_id );
294 break;
295
296 // Super sticky in all forums
297 case 'super' :
298 bbp_stick_topic( $topic_id, true );
299 break;
300
301 // We can avoid this as it is a new topic
302 case 'unstick' :
303 default :
304 break;
305 }
306 }
307
308 /** Trash Check ***************************************************/
309
310 // If the forum is trash, or the topic_status is switched to
311 // trash, trash it properly
312 if ( ( get_post_field( 'post_status', $forum_id ) == $bbp->trash_status_id ) || ( $topic_data['post_status'] == $bbp->trash_status_id ) ) {
313
314 // Trash the reply
315 wp_trash_post( $topic_id );
316
317 // Force view=all
318 $view_all = true;
319 }
320
321 /** Spam Check ****************************************************/
322
323 // If reply or topic are spam, officially spam this reply
324 if ( $topic_data['post_status'] == $bbp->spam_status_id ) {
325 add_post_meta( $topic_id, '_bbp_spam_meta_status', 'publish' );
326
327 // Force view=all
328 $view_all = true;
329 }
330
331 /** Update counts, etc... *****************************************/
332
333 do_action( 'bbp_new_topic', $topic_id, $forum_id, $anonymous_data, $topic_author );
334
335 /** Redirect ******************************************************/
336
337 // Redirect to
338 $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
339
340 // Get the topic URL
341 $topic_url = bbp_get_topic_permalink( $topic_id, $redirect_to );
342
343 // Add view all?
344 if ( bbp_get_view_all() || ( current_user_can( 'moderate' ) && !empty( $view_all ) ) )
345 $topic_url = bbp_add_view_all( $topic_url );
346
347 // Allow to be filtered
348 $topic_url = apply_filters( 'bbp_new_topic_redirect_to', $topic_url, $redirect_to );
349
350 /** Successful Save ***********************************************/
351
352 // Redirect back to new topic
353 wp_safe_redirect( $topic_url );
354
355 // For good measure
356 exit();
357
358 // Errors
359 } else {
360 $append_error = ( is_wp_error( $topic_id ) && $topic_id->get_error_message() ) ? $topic_id->get_error_message() . ' ' : '';
361 bbp_add_error( 'bbp_topic_error', __( '<strong>ERROR</strong>: The following problem(s) have been found with your topic:' . $append_error, 'bbpress' ) );
362 }
363 }
364 }
365
366 /**
367 * Handles the front end edit topic submission
368 *
369 * @uses bbPress:errors::add() To log various error messages
370 * @uses bbp_get_topic() To get the topic
371 * @uses check_admin_referer() To verify the nonce and check the referer
372 * @uses bbp_is_topic_anonymous() To check if topic is by an anonymous user
373 * @uses current_user_can() To check if the current user can edit the topic
374 * @uses bbp_filter_anonymous_post_data() To filter anonymous data
375 * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
376 * @uses esc_attr() For sanitization
377 * @uses bbp_is_forum_category() To check if the forum is a category
378 * @uses bbp_is_forum_closed() To check if the forum is closed
379 * @uses bbp_is_forum_private() To check if the forum is private
380 * @uses remove_filter() To remove 'wp_filter_kses' filters if needed
381 * @uses apply_filters() Calls 'bbp_edit_topic_pre_title' with the title and
382 * topic id
383 * @uses apply_filters() Calls 'bbp_edit_topic_pre_content' with the content
384 * and topic id
385 * @uses bbPress::errors::get_error_codes() To get the {@link WP_Error} errors
386 * @uses wp_save_post_revision() To save a topic revision
387 * @uses bbp_update_topic_revision_log() To update the topic revision log
388 * @uses bbp_stick_topic() To stick or super stick the topic
389 * @uses bbp_unstick_topic() To unstick the topic
390 * @uses wp_update_post() To update the topic
391 * @uses do_action() Calls 'bbp_edit_topic' with the topic id, forum id,
392 * anonymous data and reply author
393 * @uses bbp_move_topic_handler() To handle movement of a topic from one forum
394 * to another
395 * @uses bbp_get_topic_permalink() To get the topic permalink
396 * @uses wp_safe_redirect() To redirect to the topic link
397 * @uses bbPress::errors::get_error_messages() To get the {@link WP_Error} error
398 * messages
399 */
400 function bbp_edit_topic_handler() {
401
402 // Bail if not a POST action
403 if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
404 return;
405
406 // Bail if action is not bbp-edit-topic
407 if ( empty( $_POST['action'] ) || ( 'bbp-edit-topic' !== $_POST['action'] ) )
408 return;
409
410 // Define local variable(s)
411 $topic = $topic_id = $forum_id = $anonymous_data = 0;
412 $topic_title = $topic_content = $topic_edit_reason = '';
413 $terms = array( bbp_get_topic_tag_tax_id() => array() );
414
415 /** Topic *****************************************************************/
416
417 // Topic id was not passed
418 if ( empty( $_POST['bbp_topic_id'] ) ) {
419 bbp_add_error( 'bbp_edit_topic_id', __( '<strong>ERROR</strong>: Topic ID not found.', 'bbpress' ) );
420
421 // Topic id was passed
422 } elseif ( is_numeric( $_POST['bbp_topic_id'] ) ) {
423 $topic_id = (int) $_POST['bbp_topic_id'];
424 $topic = bbp_get_topic( $topic_id );
425 }
426
427 // Topic does not exist
428 if ( empty( $topic ) ) {
429 bbp_add_error( 'bbp_edit_topic_not_found', __( '<strong>ERROR</strong>: The topic you want to edit was not found.', 'bbpress' ) );
430
431 // Topic exists
432 } else {
433
434 // Nonce check
435 check_admin_referer( 'bbp-edit-topic_' . $topic_id );
436
437 // Check users ability to create new topic
438 if ( !bbp_is_topic_anonymous( $topic_id ) ) {
439
440 // User cannot edit this topic
441 if ( !current_user_can( 'edit_topic', $topic_id ) ) {
442 bbp_add_error( 'bbp_edit_topic_permissions', __( '<strong>ERROR</strong>: You do not have permission to edit that topic.', 'bbpress' ) );
443 }
444
445 // It is an anonymous post
446 } else {
447
448 // Filter anonymous data
449 $anonymous_data = bbp_filter_anonymous_post_data( array(), true );
450 }
451 }
452
453 // Remove wp_filter_kses filters from title and content for capable users and if the nonce is verified
454 if ( current_user_can( 'unfiltered_html' ) && !empty( $_POST['_bbp_unfiltered_html_topic'] ) && ( wp_create_nonce( 'bbp-unfiltered-html-topic_' . $topic_id ) == $_POST['_bbp_unfiltered_html_topic'] ) ) {
455 remove_filter( 'bbp_edit_topic_pre_title', 'wp_filter_kses' );
456 remove_filter( 'bbp_edit_topic_pre_content', 'wp_filter_kses' );
457 }
458
459 /** Topic Forum ***********************************************************/
460
461 // Forum id was not passed
462 if ( empty( $_POST['bbp_forum_id'] ) ) {
463 bbp_add_error( 'bbp_topic_forum_id', __( '<strong>ERROR</strong>: Forum ID is missing.', 'bbpress' ) );
464
465 // Forum id was passed
466 } elseif ( is_numeric( $_POST['bbp_forum_id'] ) ) {
467 $forum_id = (int) $_POST['bbp_forum_id'];
468 }
469
470 // Current forum this topic is in
471 $current_forum_id = bbp_get_topic_forum_id( $topic_id );
472
473 // Forum exists
474 if ( !empty( $forum_id ) && ( $forum_id !== $current_forum_id ) ) {
475
476 // Forum is a category
477 if ( bbp_is_forum_category( $forum_id ) )
478 bbp_add_error( 'bbp_edit_topic_forum_category', __( '<strong>ERROR</strong>: This forum is a category. No topics can be created in it.', 'bbpress' ) );
479
480 // Forum is closed and user cannot access
481 if ( bbp_is_forum_closed( $forum_id ) && !current_user_can( 'edit_forum', $forum_id ) )
482 bbp_add_error( 'bbp_edit_topic_forum_closed', __( '<strong>ERROR</strong>: This forum has been closed to new topics.', 'bbpress' ) );
483
484 // Forum is private and user cannot access
485 if ( bbp_is_forum_private( $forum_id ) && !current_user_can( 'read_private_forums' ) )
486 bbp_add_error( 'bbp_edit_topic_forum_private', __( '<strong>ERROR</strong>: This forum is private and you do not have the capability to read or create new topics in it.', 'bbpress' ) );
487
488 // Forum is hidden and user cannot access
489 if ( bbp_is_forum_hidden( $forum_id ) && !current_user_can( 'read_hidden_forums' ) )
490 bbp_add_error( 'bbp_edit_topic_forum_hidden', __( '<strong>ERROR</strong>: This forum is hidden and you do not have the capability to read or create new topics in it.', 'bbpress' ) );
491 }
492
493 /** Topic Title ***********************************************************/
494
495 if ( !empty( $_POST['bbp_topic_title'] ) )
496 $topic_title = esc_attr( strip_tags( $_POST['bbp_topic_title'] ) );
497
498 // Filter and sanitize
499 $topic_title = apply_filters( 'bbp_edit_topic_pre_title', $topic_title, $topic_id );
500
501 // No topic title
502 if ( empty( $topic_title ) )
503 bbp_add_error( 'bbp_edit_topic_title', __( '<strong>ERROR</strong>: Your topic needs a title.', 'bbpress' ) );
504
505 /** Topic Content *********************************************************/
506
507 if ( !empty( $_POST['bbp_topic_content'] ) )
508 $topic_content = $_POST['bbp_topic_content'];
509
510 // Filter and sanitize
511 $topic_content = apply_filters( 'bbp_edit_topic_pre_content', $topic_content, $topic_id );
512
513 // No topic content
514 if ( empty( $topic_content ) )
515 bbp_add_error( 'bbp_edit_topic_content', __( '<strong>ERROR</strong>: Your topic cannot be empty.', 'bbpress' ) );
516
517 /** topic Blacklist *******************************************************/
518
519 if ( !bbp_check_for_blacklist( $anonymous_data, bbp_get_topic_author_id( $topic_id ), $topic_title, $topic_content ) )
520 bbp_add_error( 'bbp_topic_blacklist', __( '<strong>ERROR</strong>: Your topic cannot be edited at this time.', 'bbpress' ) );
521
522 /** Topic Tags ************************************************************/
523
524 // Tags
525 if ( !empty( $_POST['bbp_topic_tags'] ) ) {
526
527 // Escape tag input
528 $terms = esc_attr( strip_tags( $_POST['bbp_topic_tags'] ) );
529
530 // Explode by comma
531 if ( strstr( $terms, ',' ) )
532 $terms = explode( ',', $terms );
533
534 // Add topic tag ID as main key
535 $terms = array( bbp_get_topic_tag_tax_id() => $terms );
536 }
537
538 /** Additional Actions (Before Save) **************************************/
539
540 do_action( 'bbp_edit_topic_pre_extras', $topic_id );
541
542 /** No Errors *************************************************************/
543
544 if ( !bbp_has_errors() ) {
545
546 /** Stickies **********************************************************/
547
548 if ( !empty( $_POST['bbp_stick_topic'] ) && in_array( $_POST['bbp_stick_topic'], array( 'stick', 'super', 'unstick' ) ) ) {
549
550 // What's the dilly?
551 switch ( $_POST['bbp_stick_topic'] ) {
552
553 // Sticky in forum
554 case 'stick' :
555 bbp_stick_topic( $topic_id );
556 break;
557
558 // Sticky in all forums
559 case 'super' :
560 bbp_stick_topic( $topic_id, true );
561 break;
562
563 // Normal
564 case 'unstick' :
565 default :
566 bbp_unstick_topic( $topic_id );
567 break;
568 }
569 }
570
571 /** Update the topic **************************************************/
572
573 // Add the content of the form to $post as an array
574 $topic_data = array(
575 'ID' => $topic_id,
576 'post_title' => $topic_title,
577 'post_content' => $topic_content,
578 'post_parent' => $forum_id,
579 'tax_input' => $terms,
580 );
581
582 // Just in time manipulation of topic data before being edited
583 $topic_data = apply_filters( 'bbp_edit_topic_pre_insert', $topic_data );
584
585 // Insert topic
586 $topic_id = wp_update_post( $topic_data );
587
588 /** Revisions *********************************************************/
589
590 // Revision Reason
591 if ( !empty( $_POST['bbp_topic_edit_reason'] ) )
592 $topic_edit_reason = esc_attr( strip_tags( $_POST['bbp_topic_edit_reason'] ) );
593
594 // Update revision log
595 if ( !empty( $_POST['bbp_log_topic_edit'] ) && ( 1 == $_POST['bbp_log_topic_edit'] ) && ( $revision_id = wp_save_post_revision( $topic_id ) ) ) {
596 bbp_update_topic_revision_log( array(
597 'topic_id' => $topic_id,
598 'revision_id' => $revision_id,
599 'author_id' => bbp_get_current_user_id(),
600 'reason' => $topic_edit_reason
601 ) );
602 }
603
604 /** No Errors *********************************************************/
605
606 if ( !empty( $topic_id ) && !is_wp_error( $topic_id ) ) {
607
608 // Update counts, etc...
609 do_action( 'bbp_edit_topic', $topic_id, $forum_id, $anonymous_data, $topic->post_author , true /* Is edit */ );
610
611 // If the new forum id is not equal to the old forum id, run the
612 // bbp_move_topic action and pass the topic's forum id as the
613 // first arg and topic id as the second to update counts.
614 if ( $forum_id != $topic->post_parent )
615 bbp_move_topic_handler( $topic_id, $topic->post_parent, $forum_id );
616
617 /** Additional Actions (After Save) *******************************/
618
619 do_action( 'bbp_edit_topic_post_extras', $topic_id );
620
621 /** Redirect ******************************************************/
622
623 // Redirect to
624 $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
625
626 // View all?
627 $view_all = bbp_get_view_all();
628
629 // Get the topic URL
630 $topic_url = bbp_get_topic_permalink( $topic_id, $redirect_to );
631
632 // Add view all?
633 if ( !empty( $view_all ) )
634 $topic_url = bbp_add_view_all( $topic_url );
635
636 // Allow to be filtered
637 $topic_url = apply_filters( 'bbp_edit_topic_redirect_to', $topic_url, $view_all, $redirect_to );
638
639 /** Successful Edit ***********************************************/
640
641 // Redirect back to new topic
642 wp_safe_redirect( $topic_url );
643
644 // For good measure
645 exit();
646
647 /** Errors ************************************************************/
648
649 } else {
650 $append_error = ( is_wp_error( $topic_id ) && $topic_id->get_error_message() ) ? $topic_id->get_error_message() . ' ' : '';
651 bbp_add_error( 'bbp_topic_error', __( '<strong>ERROR</strong>: The following problem(s) have been found with your topic:' . $append_error . 'Please try again.', 'bbpress' ) );
652 }
653 }
654 }
655
656 /**
657 * Handle all the extra meta stuff from posting a new topic
658 *
659 * @param int $topic_id Optional. Topic id
660 * @param int $forum_id Optional. Forum id
661 * @param bool|array $anonymous_data Optional. If it is an array, it is
662 * extracted and anonymous user info is saved
663 * @param int $author_id Author id
664 * @param bool $is_edit Optional. Is the post being edited? Defaults to false.
665 * @uses bbp_get_topic_id() To get the topic id
666 * @uses bbp_get_forum_id() To get the forum id
667 * @uses bbp_get_current_user_id() To get the current user id
668 * @yses bbp_get_topic_forum_id() To get the topic forum id
669 * @uses update_post_meta() To update the topic metas
670 * @uses set_transient() To update the flood check transient for the ip
671 * @uses update_user_meta() To update the last posted meta for the user
672 * @uses bbp_is_subscriptions_active() To check if the subscriptions feature is
673 * activated or not
674 * @uses bbp_is_user_subscribed() To check if the user is subscribed
675 * @uses bbp_remove_user_subscription() To remove the user's subscription
676 * @uses bbp_add_user_subscription() To add the user's subscription
677 * @uses bbp_update_topic_forum_id() To update the topic's forum id
678 * @uses bbp_update_topic_topic_id() To update the topic's topic id
679 * @uses bbp_update_topic_last_reply_id() To update the last reply id topic meta
680 * @uses bbp_update_topic_last_active_id() To update the topic last active id
681 * @uses bbp_update_topic_last_active_time() To update the last active topic meta
682 * @uses bbp_update_topic_reply_count() To update the topic reply count
683 * @uses bbp_update_topic_reply_count_hidden() To udpate the topic hidden reply count
684 * @uses bbp_update_topic_voice_count() To update the topic voice count
685 * @uses bbp_update_topic_walker() To udpate the topic's ancestors
686 */
687 function bbp_update_topic( $topic_id = 0, $forum_id = 0, $anonymous_data = false, $author_id = 0, $is_edit = false ) {
688
689 // Validate the ID's passed from 'bbp_new_topic' action
690 $topic_id = bbp_get_topic_id( $topic_id );
691 $forum_id = bbp_get_forum_id( $forum_id );
692
693 // Check author_id
694 if ( empty( $author_id ) )
695 $author_id = bbp_get_current_user_id();
696
697 // Check forum_id
698 if ( empty( $forum_id ) )
699 $forum_id = bbp_get_topic_forum_id( $topic_id );
700
701 // If anonymous post, store name, email, website and ip in post_meta.
702 // It expects anonymous_data to be sanitized.
703 // Check bbp_filter_anonymous_post_data() for sanitization.
704 if ( !empty( $anonymous_data ) && is_array( $anonymous_data ) ) {
705 extract( $anonymous_data );
706
707 update_post_meta( $topic_id, '_bbp_anonymous_name', $bbp_anonymous_name, false );
708 update_post_meta( $topic_id, '_bbp_anonymous_email', $bbp_anonymous_email, false );
709
710 // Set transient for throttle check (only on new, not edit)
711 if ( empty( $is_edit ) )
712 set_transient( '_bbp_' . bbp_current_author_ip() . '_last_posted', time() );
713
714 // Website is optional
715 if ( !empty( $bbp_anonymous_website ) )
716 update_post_meta( $topic_id, '_bbp_anonymous_website', $bbp_anonymous_website, false );
717 } else {
718 if ( empty( $is_edit ) && !current_user_can( 'throttle' ) )
719 update_user_meta( $author_id, '_bbp_last_posted', time() );
720 }
721
722 // Handle Subscription Checkbox
723 if ( bbp_is_subscriptions_active() && !empty( $author_id ) ) {
724 $subscribed = bbp_is_user_subscribed( $author_id, $topic_id );
725 $subscheck = ( !empty( $_POST['bbp_topic_subscription'] ) && ( 'bbp_subscribe' == $_POST['bbp_topic_subscription'] ) ) ? true : false;
726
727 // Subscribed and unsubscribing
728 if ( true == $subscribed && false == $subscheck )
729 bbp_remove_user_subscription( $author_id, $topic_id );
730
731 // Subscribing
732 elseif ( false == $subscribed && true == $subscheck )
733 bbp_add_user_subscription( $author_id, $topic_id );
734 }
735
736 // Forum topic meta
737 bbp_update_topic_forum_id( $topic_id, $forum_id );
738 bbp_update_topic_topic_id( $topic_id, $topic_id );
739
740 // Update associated topic values if this is a new topic
741 if ( empty( $is_edit ) ) {
742
743 // Update poster IP if not editing
744 update_post_meta( $topic_id, '_bbp_author_ip', bbp_current_author_ip(), false );
745
746 // Last active time
747 $last_active = current_time( 'mysql' );
748
749 // Reply topic meta
750 bbp_update_topic_last_reply_id ( $topic_id, 0 );
751 bbp_update_topic_last_active_id ( $topic_id, $topic_id );
752 bbp_update_topic_last_active_time ( $topic_id, $last_active );
753 bbp_update_topic_reply_count ( $topic_id, 0 );
754 bbp_update_topic_reply_count_hidden ( $topic_id, 0 );
755 bbp_update_topic_voice_count ( $topic_id );
756
757 // Walk up ancestors and do the dirty work
758 bbp_update_topic_walker( $topic_id, $last_active, $forum_id, 0, false );
759 }
760 }
761
762 /**
763 * Walks up the post_parent tree from the current topic_id, and updates the
764 * counts of forums above it. This calls a few internal functions that all run
765 * manual queries against the database to get their results. As such, this
766 * function can be costly to run but is necessary to keep everything accurate.
767 *
768 * @since bbPress (r2800)
769 * @param int $topic_id Topic id
770 * @param string $last_active_time Optional. Last active time
771 * @param int $forum_id Optional. Forum id
772 * @param int $reply_id Optional. Reply id
773 * @param bool $refresh Reset all the previous parameters? Defaults to true.
774 * @uses bbp_get_topic_id() To get the topic id
775 * @uses bbp_get_topic_forum_id() To get the topic forum id
776 * @uses get_post_ancestors() To get the topic's ancestors
777 * @uses bbp_is_forum() To check if the ancestor is a forum
778 * @uses bbp_update_forum() To update the forum
779 */
780 function bbp_update_topic_walker( $topic_id, $last_active_time = '', $forum_id = 0, $reply_id = 0, $refresh = true ) {
781
782 // Validate topic_id
783 $topic_id = bbp_get_topic_id( $topic_id );
784
785 // Topic was passed
786 if ( !empty( $topic_id ) ) {
787
788 // Get the forum ID if none was passed
789 if ( empty( $forum_id ) ) {
790 $forum_id = bbp_get_topic_forum_id( $topic_id );
791 }
792
793 // Set the active_id based on topic_id/reply_id
794 $active_id = empty( $reply_id ) ? $topic_id : $reply_id;
795 }
796
797 // Get topic ancestors
798 $ancestors = array_values( array_unique( array_merge( array( $forum_id ), get_post_ancestors( $topic_id ) ) ) );
799
800 // If we want a full refresh, unset any of the possibly passed variables
801 if ( true == $refresh )
802 $forum_id = $topic_id = $reply_id = $active_id = $last_active_time = 0;
803
804 // Loop through ancestors
805 foreach ( $ancestors as $ancestor ) {
806
807 // If ancestor is a forum, update counts
808 if ( bbp_is_forum( $ancestor ) ) {
809
810 // Update the forum
811 bbp_update_forum( array(
812 'forum_id' => $ancestor,
813 'last_topic_id' => $topic_id,
814 'last_reply_id' => $reply_id,
815 'last_active_id' => $active_id,
816 'last_active_time' => 0,
817 ) );
818 }
819 }
820 }
821
822 /**
823 * Handle the moving of a topic from one forum to another. This includes walking
824 * up the old and new branches and updating the counts.
825 *
826 * @param int $topic_id Topic id
827 * @param int $old_forum_id Old forum id
828 * @param int $new_forum_id New forum id
829 * @uses bbp_get_topic_id() To get the topic id
830 * @uses bbp_get_forum_id() To get the forum id
831 * @uses bbp_get_reply_post_type() To get the reply post type
832 * @uses bbp_get_public_child_ids() To get the public child ids
833 * @uses bbp_update_reply_forum_id() To update the reply forum id
834 * @uses bbp_update_topic_forum_id() To update the topic forum id
835 * @uses get_post_ancestors() To get the topic's ancestors
836 * @uses bbp_is_forum() To check if the ancestor is a forum
837 * @uses bbp_update_forum() To update the forum
838 */
839 function bbp_move_topic_handler( $topic_id, $old_forum_id, $new_forum_id ) {
840 $topic_id = bbp_get_topic_id( $topic_id );
841 $old_forum_id = bbp_get_forum_id( $old_forum_id );
842 $new_forum_id = bbp_get_forum_id( $new_forum_id );
843 $replies = bbp_get_public_child_ids( $topic_id, bbp_get_reply_post_type() );
844
845 // Update the forum_id of all replies in the topic
846 foreach ( $replies as $reply_id )
847 bbp_update_reply_forum_id( $reply_id, $new_forum_id );
848
849 // Forum topic meta
850 bbp_update_topic_forum_id( $topic_id, $new_forum_id );
851
852 /** Old forum_id **********************************************************/
853
854 // Get topic ancestors
855 $ancestors = array_values( array_unique( array_merge( array( $old_forum_id ), get_post_ancestors( $old_forum_id ) ) ) );
856
857 // Loop through ancestors
858 foreach ( $ancestors as $ancestor ) {
859
860 // If ancestor is a forum, update counts
861 if ( bbp_is_forum( $ancestor ) ) {
862
863 // Update the forum
864 bbp_update_forum( array(
865 'forum_id' => $ancestor,
866 ) );
867 }
868 }
869
870 /** New forum_id **********************************************************/
871
872 // Make sure we're not walking twice
873 if ( !in_array( $new_forum_id, $ancestors ) ) {
874
875 // Get topic ancestors
876 $ancestors = array_values( array_unique( array_merge( array( $new_forum_id ), get_post_ancestors( $new_forum_id ) ) ) );
877
878 // Loop through ancestors
879 foreach ( $ancestors as $ancestor ) {
880
881 // If ancestor is a forum, update counts
882 if ( bbp_is_forum( $ancestor ) ) {
883
884 // Update the forum
885 bbp_update_forum( array(
886 'forum_id' => $ancestor,
887 ) );
888 }
889 }
890 }
891 }
892
893 /**
894 * Merge topic handler
895 *
896 * Handles the front end merge topic submission
897 *
898 * @since bbPress (r2756)
899 *
900 * @uses bbPress:errors::add() To log various error messages
901 * @uses bbp_get_topic() To get the topics
902 * @uses check_admin_referer() To verify the nonce and check the referer
903 * @uses current_user_can() To check if the current user can edit the topics
904 * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
905 * @uses do_action() Calls 'bbp_merge_topic' with the destination and source
906 * topic ids
907 * @uses bbp_get_topic_subscribers() To get the source topic subscribers
908 * @uses bbp_add_user_subscription() To add the user subscription
909 * @uses bbp_remove_user_subscription() To remove the user subscription
910 * @uses bbp_get_topic_favoriters() To get the source topic favoriters
911 * @uses bbp_add_user_favorite() To add the user favorite
912 * @uses bbp_remove_user_favorite() To remove the user favorite
913 * @uses wp_get_post_terms() To get the source topic tags
914 * @uses wp_set_post_terms() To set the topic tags
915 * @uses wp_delete_object_term_relationships() To delete the topic tags
916 * @uses bbp_open_topic() To open the topic
917 * @uses bbp_unstick_topic() To unstick the topic
918 * @uses bbp_get_reply_post_type() To get the reply post type
919 * @uses get_posts() To get the replies
920 * @uses wp_update_post() To update the topic
921 * @uses bbp_update_reply_topic_id() To update the reply topic id
922 * @uses bbp_get_topic_forum_id() To get the topic forum id
923 * @uses bbp_update_reply_forum_id() To update the reply forum id
924 * @uses do_action() Calls 'bbp_merged_topic_reply' with the reply id and
925 * destination topic id
926 * @uses do_action() Calls 'bbp_merged_topic' with the destination and source
927 * topic ids and source topic's forum id
928 * @uses bbp_get_topic_permalink() To get the topic permalink
929 * @uses wp_redirect() To redirect to the topic link
930 */
931 function bbp_merge_topic_handler() {
932
933 // Bail if not a POST action
934 if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
935 return;
936
937 // Bail if action is not bbp-merge-topic
938 if ( empty( $_POST['action'] ) || ( 'bbp-merge-topic' !== $_POST['action'] ) )
939 return;
940
941 // Define local variable(s)
942 $source_topic_id = $destination_topic_id = 0;
943 $source_topic = $destination_topic = 0;
944 $subscribers = $favoriters = $replies = array();
945
946 /** Source Topic **********************************************************/
947
948 // Topic id
949 if ( empty( $_POST['bbp_topic_id'] ) )
950 bbp_add_error( 'bbp_merge_topic_source_id', __( '<strong>ERROR</strong>: Topic ID not found.', 'bbpress' ) );
951 else
952 $source_topic_id = (int) $_POST['bbp_topic_id'];
953
954 // Nonce check
955 check_admin_referer( 'bbp-merge-topic_' . $source_topic_id );
956
957 // Source topic not found
958 if ( !$source_topic = bbp_get_topic( $source_topic_id ) )
959 bbp_add_error( 'bbp_merge_topic_source_not_found', __( '<strong>ERROR</strong>: The topic you want to merge was not found.', 'bbpress' ) );
960
961 // Cannot edit source topic
962 if ( !current_user_can( 'edit_topic', $source_topic->ID ) )
963 bbp_add_error( 'bbp_merge_topic_source_permission', __( '<strong>ERROR</strong>: You do not have the permissions to edit the source topic.', 'bbpress' ) );
964
965 /** Destination Topic *****************************************************/
966
967 // Topic id
968 if ( empty( $_POST['bbp_destination_topic'] ) )
969 bbp_add_error( 'bbp_merge_topic_destination_id', __( '<strong>ERROR</strong>: Destination topic ID not found.', 'bbpress' ) );
970 else
971 $destination_topic_id = (int) $_POST['bbp_destination_topic'];
972
973 // Destination topic not found
974 if ( !$destination_topic = bbp_get_topic( $destination_topic_id ) )
975 bbp_add_error( 'bbp_merge_topic_destination_not_found', __( '<strong>ERROR</strong>: The topic you want to merge to was not found.', 'bbpress' ) );
976
977 // Cannot edit destination topic
978 if ( !current_user_can( 'edit_topic', $destination_topic->ID ) )
979 bbp_add_error( 'bbp_merge_topic_destination_permission', __( '<strong>ERROR</strong>: You do not have the permissions to edit the destination topic.', 'bbpress' ) );
980
981 /** No Errors *************************************************************/
982
983 if ( !bbp_has_errors() ) {
984
985 // Update counts, etc...
986 do_action( 'bbp_merge_topic', $destination_topic->ID, $source_topic->ID );
987
988 /** Date Check ********************************************************/
989
990 // Check if the destination topic is older than the source topic
991 if ( strtotime( $source_topic->post_date ) < strtotime( $destination_topic->post_date ) ) {
992
993 // Set destination topic post_date to 1 second before source topic
994 $destination_post_date = date( 'Y-m-d H:i:s', strtotime( $source_topic->post_date ) - 1 );
995
996 $postarr = array(
997 'ID' => $destination_topic_id,
998 'post_date' => $destination_post_date,
999 'post_date_gmt' => get_gmt_from_date( $destination_post_date )
1000 );
1001
1002 // Update destination topic
1003 wp_update_post( $postarr );
1004 }
1005
1006 /** Subscriptions *****************************************************/
1007
1008 // Get subscribers from source topic
1009 $subscribers = bbp_get_topic_subscribers( $source_topic->ID );
1010
1011 // Remove the topic from everybody's subscriptions
1012 if ( !empty( $subscribers ) ) {
1013
1014 // Loop through each user
1015 foreach ( (array) $subscribers as $subscriber ) {
1016
1017 // Shift the subscriber if told to
1018 if ( !empty( $_POST['bbp_topic_subscribers'] ) && ( 1 == $_POST['bbp_topic_subscribers'] ) && bbp_is_subscriptions_active() )
1019 bbp_add_user_subscription( $subscriber, $destination_topic->ID );
1020
1021 // Remove old subscription
1022 bbp_remove_user_subscription( $subscriber, $source_topic->ID );
1023 }
1024 }
1025
1026 /** Favorites *********************************************************/
1027
1028 // Get favoriters from source topic
1029 $favoriters = bbp_get_topic_favoriters( $source_topic->ID );
1030
1031 // Remove the topic from everybody's favorites
1032 if ( !empty( $favoriters ) ) {
1033
1034 // Loop through each user
1035 foreach ( (array) $favoriters as $favoriter ) {
1036
1037 // Shift the favoriter if told to
1038 if ( !empty( $_POST['bbp_topic_favoriters'] ) && 1 == $_POST['bbp_topic_favoriters'] )
1039 bbp_add_user_favorite( $favoriter, $destination_topic->ID );
1040
1041 // Remove old favorite
1042 bbp_remove_user_favorite( $favoriter, $source_topic->ID );
1043 }
1044 }
1045
1046 /** Tags **************************************************************/
1047
1048 // Get the source topic tags
1049 $source_topic_tags = wp_get_post_terms( $source_topic->ID, bbp_get_topic_tag_tax_id(), array( 'fields' => 'names' ) );
1050
1051 // Tags to possibly merge
1052 if ( !empty( $source_topic_tags ) && !is_wp_error( $source_topic_tags ) ) {
1053
1054 // Shift the tags if told to
1055 if ( !empty( $_POST['bbp_topic_tags'] ) && ( 1 == $_POST['bbp_topic_tags'] ) )
1056 wp_set_post_terms( $destination_topic->ID, $source_topic_tags, bbp_get_topic_tag_tax_id(), true );
1057
1058 // Delete the tags from the source topic
1059 wp_delete_object_term_relationships( $source_topic->ID, bbp_get_topic_tag_tax_id() );
1060 }
1061
1062 /** Source Topic ******************************************************/
1063
1064 // Status
1065 bbp_open_topic( $source_topic->ID );
1066
1067 // Sticky
1068 bbp_unstick_topic( $source_topic->ID );
1069
1070 // Get the replies of the source topic
1071 $replies = (array) get_posts( array(
1072 'post_parent' => $source_topic->ID,
1073 'post_type' => bbp_get_reply_post_type(),
1074 'posts_per_page' => -1,
1075 'order' => 'ASC'
1076 ) );
1077
1078 // Prepend the source topic to its replies array for processing
1079 array_unshift( $replies, $source_topic );
1080
1081 if ( !empty( $replies ) ) {
1082
1083 /** Merge Replies *************************************************/
1084
1085 // Change the post_parent of each reply to the destination topic id
1086 foreach ( $replies as $reply ) {
1087 $postarr = array(
1088 'ID' => $reply->ID,
1089 'post_title' => sprintf( __( 'Reply To: %s', 'bbpress' ), $destination_topic->post_title ),
1090 'post_name' => false,
1091 'post_type' => bbp_get_reply_post_type(),
1092 'post_parent' => $destination_topic->ID,
1093 'guid' => ''
1094 );
1095
1096 wp_update_post( $postarr );
1097
1098 // Adjust reply meta values
1099 bbp_update_reply_topic_id( $reply->ID, $destination_topic->ID );
1100 bbp_update_reply_forum_id( $reply->ID, bbp_get_topic_forum_id( $destination_topic->ID ) );
1101
1102 // Do additional actions per merged reply
1103 do_action( 'bbp_merged_topic_reply', $reply->ID, $destination_topic->ID );
1104 }
1105 }
1106
1107 /** Successful Merge **************************************************/
1108
1109 // Send the post parent of the source topic as it has been shifted
1110 // (possibly to a new forum) so we need to update the counts of the
1111 // old forum as well as the new one
1112 do_action( 'bbp_merged_topic', $destination_topic->ID, $source_topic->ID, $source_topic->post_parent );
1113
1114 // Redirect back to new topic
1115 wp_redirect( bbp_get_topic_permalink( $destination_topic->ID ) );
1116
1117 // For good measure
1118 exit();
1119 }
1120 }
1121
1122 /**
1123 * Fix counts on topic merge
1124 *
1125 * When a topic is merged, update the counts of source and destination topic
1126 * and their forums.
1127 *
1128 * @since bbPress (r2756)
1129 *
1130 * @param int $destination_topic_id Destination topic id
1131 * @param int $source_topic_id Source topic id
1132 * @param int $source_topic_forum Source topic's forum id
1133 * @uses bbp_update_forum_topic_count() To update the forum topic counts
1134 * @uses bbp_update_forum_reply_count() To update the forum reply counts
1135 * @uses bbp_update_topic_reply_count() To update the topic reply counts
1136 * @uses bbp_update_topic_voice_count() To update the topic voice counts
1137 * @uses bbp_update_topic_reply_count_hidden() To update the topic hidden reply
1138 * count
1139 * @uses do_action() Calls 'bbp_merge_topic_count' with the destination topic
1140 * id, source topic id & source topic forum id
1141 */
1142 function bbp_merge_topic_count( $destination_topic_id, $source_topic_id, $source_topic_forum_id ) {
1143
1144 /** Source Topic **********************************************************/
1145
1146 // Forum Topic Counts
1147 bbp_update_forum_topic_count( $source_topic_forum_id );
1148
1149 // Forum Reply Counts
1150 bbp_update_forum_reply_count( $source_topic_forum_id );
1151
1152 /** Destination Topic *****************************************************/
1153
1154 // Topic Reply Counts
1155 bbp_update_topic_reply_count( $destination_topic_id );
1156
1157 // Topic Hidden Reply Counts
1158 bbp_update_topic_reply_count_hidden( $destination_topic_id );
1159
1160 // Topic Voice Counts
1161 bbp_update_topic_voice_count( $destination_topic_id );
1162
1163 do_action( 'bbp_merge_topic_count', $destination_topic_id, $source_topic_id, $source_topic_forum_id );
1164 }
1165
1166 /**
1167 * Split topic handler
1168 *
1169 * Handles the front end split topic submission
1170 *
1171 * @since bbPress (r2756)
1172 *
1173 * @uses bbPress:errors::add() To log various error messages
1174 * @uses bbp_get_reply() To get the reply
1175 * @uses bbp_get_topic() To get the topics
1176 * @uses check_admin_referer() To verify the nonce and check the referer
1177 * @uses current_user_can() To check if the current user can edit the topics
1178 * @uses bbp_get_topic_post_type() To get the topic post type
1179 * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
1180 * @uses do_action() Calls 'bbp_pre_split_topic' with the from reply id, source
1181 * and destination topic ids
1182 * @uses bbp_get_topic_subscribers() To get the source topic subscribers
1183 * @uses bbp_add_user_subscription() To add the user subscription
1184 * @uses bbp_get_topic_favoriters() To get the source topic favoriters
1185 * @uses bbp_add_user_favorite() To add the user favorite
1186 * @uses wp_get_post_terms() To get the source topic tags
1187 * @uses wp_set_post_terms() To set the topic tags
1188 * @uses bbp_get_reply_post_type() To get the reply post type
1189 * @uses wpdb::prepare() To prepare our sql query
1190 * @uses wpdb::get_results() To execute the sql query and get results
1191 * @uses wp_update_post() To update the replies
1192 * @uses bbp_update_reply_topic_id() To update the reply topic id
1193 * @uses bbp_get_topic_forum_id() To get the topic forum id
1194 * @uses bbp_update_reply_forum_id() To update the reply forum id
1195 * @uses do_action() Calls 'bbp_split_topic_reply' with the reply id and
1196 * destination topic id
1197 * @uses bbp_update_topic_last_reply_id() To update the topic last reply id
1198 * @uses bbp_update_topic_last_active_time() To update the topic last active meta
1199 * @uses do_action() Calls 'bbp_post_split_topic' with the destination and
1200 * source topic ids and source topic's forum id
1201 * @uses bbp_get_topic_permalink() To get the topic permalink
1202 * @uses wp_redirect() To redirect to the topic link
1203 */
1204 function bbp_split_topic_handler() {
1205
1206 // Bail if not a POST action
1207 if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
1208 return;
1209
1210 // Bail if action is not 'bbp-split-topic'
1211 if ( empty( $_POST['action'] ) || ( 'bbp-split-topic' !== $_POST['action'] ) )
1212 return;
1213
1214 global $wpdb, $bbp;
1215
1216 // Prevent debug notices
1217 $from_reply_id = $destination_topic_id = 0;
1218 $destination_topic_title = '';
1219 $destination_topic = $from_reply = $source_topic = '';
1220 $split_option = false;
1221
1222 /** Split Reply ***********************************************************/
1223
1224 if ( empty( $_POST['bbp_reply_id'] ) )
1225 bbp_add_error( 'bbp_split_topic_reply_id', __( '<strong>ERROR</strong>: Reply ID to split the topic from not found!', 'bbpress' ) );
1226 else
1227 $from_reply_id = (int) $_POST['bbp_reply_id'];
1228
1229 $from_reply = bbp_get_reply( $from_reply_id );
1230
1231 // Reply exists
1232 if ( empty( $from_reply ) )
1233 bbp_add_error( 'bbp_split_topic_r_not_found', __( '<strong>ERROR</strong>: The reply you want to split from was not found.', 'bbpress' ) );
1234
1235 /** Topic to Split ********************************************************/
1236
1237 // Get the topic being split
1238 $source_topic = bbp_get_topic( $from_reply->post_parent );
1239
1240 // No topic
1241 if ( empty( $source_topic ) )
1242 bbp_add_error( 'bbp_split_topic_source_not_found', __( '<strong>ERROR</strong>: The topic you want to split was not found.', 'bbpress' ) );
1243
1244 // Nonce check
1245 check_admin_referer( 'bbp-split-topic_' . $source_topic->ID );
1246
1247 // Use cannot edit topic
1248 if ( !current_user_can( 'edit_topic', $source_topic->ID ) )
1249 bbp_add_error( 'bbp_split_topic_source_permission', __( '<strong>ERROR</strong>: You do not have the permissions to edit the source topic.', 'bbpress' ) );
1250
1251 /** How to Split **********************************************************/
1252
1253 if ( !empty( $_POST['bbp_topic_split_option'] ) )
1254 $split_option = (string) trim( $_POST['bbp_topic_split_option'] );
1255
1256 // Invalid split option
1257 if ( empty( $split_option ) || !in_array( $split_option, array( 'existing', 'reply' ) ) ) {
1258 bbp_add_error( 'bbp_split_topic_option', __( '<strong>ERROR</strong>: You need to choose a valid split option.', 'bbpress' ) );
1259
1260 // Valid Split Option
1261 } else {
1262
1263 // What kind of split
1264 switch ( $split_option ) {
1265
1266 // Into an existing topic
1267 case 'existing' :
1268
1269 // Get destination topic id
1270 if ( empty( $_POST['bbp_destination_topic'] ) )
1271 bbp_add_error( 'bbp_split_topic_destination_id', __( '<strong>ERROR</strong>: Destination topic ID not found!', 'bbpress' ) );
1272 else
1273 $destination_topic_id = (int) $_POST['bbp_destination_topic'];
1274
1275 // Get the destination topic
1276 $destination_topic = bbp_get_topic( $destination_topic_id );
1277
1278 // No destination topic
1279 if ( empty( $destination_topic ) )
1280 bbp_add_error( 'bbp_split_topic_destination_not_found', __( '<strong>ERROR</strong>: The topic you want to split to was not found!', 'bbpress' ) );
1281
1282 // User cannot edit the destination topic
1283 if ( !current_user_can( 'edit_topic', $destination_topic->ID ) )
1284 bbp_add_error( 'bbp_split_topic_destination_permission', __( '<strong>ERROR</strong>: You do not have the permissions to edit the destination topic!', 'bbpress' ) );
1285
1286 break;
1287
1288 // Split at reply into a new topic
1289 case 'reply' :
1290 default :
1291
1292 // User needs to be able to publish topics
1293 if ( current_user_can( 'publish_topics' ) ) {
1294
1295 // Use the new title that was passed
1296 if ( !empty( $_POST['bbp_topic_split_destination_title'] ) ) {
1297 $destination_topic_title = esc_attr( strip_tags( $_POST['bbp_topic_split_destination_title'] ) );
1298
1299 // Use the source topic title
1300 } else {
1301 $destination_topic_title = $source_topic->post_title;
1302 }
1303
1304 // Setup the updated topic parameters
1305 $postarr = array(
1306 'ID' => $from_reply->ID,
1307 'post_title' => $destination_topic_title,
1308 'post_name' => false,
1309 'post_type' => bbp_get_topic_post_type(),
1310 'post_parent' => $source_topic->post_parent,
1311 'guid' => ''
1312 );
1313
1314 // Update the topic
1315 $destination_topic_id = wp_update_post( $postarr );
1316 $destination_topic = bbp_get_topic( $destination_topic_id );
1317
1318 // Make sure the new topic knows its a topic
1319 bbp_update_topic_topic_id( $from_reply->ID );
1320
1321 // Shouldn't happen
1322 if ( false == $destination_topic_id || is_wp_error( $destination_topic_id ) || empty( $destination_topic ) ) {
1323 bbp_add_error( 'bbp_split_topic_destination_reply', __( '<strong>ERROR</strong>: There was a problem converting the reply into the topic. Please try again.', 'bbpress' ) );
1324 }
1325
1326 // User cannot publish posts
1327 } else {
1328 bbp_add_error( 'bbp_split_topic_destination_permission', __( '<strong>ERROR</strong>: You do not have the permissions to create new topics. The reply could not be converted into a topic.', 'bbpress' ) );
1329 }
1330
1331 break;
1332 }
1333 }
1334
1335 /** No Errors - Do the Spit ***********************************************/
1336
1337 if ( !bbp_has_errors() ) {
1338
1339 // Update counts, etc...
1340 do_action( 'bbp_pre_split_topic', $from_reply->ID, $source_topic->ID, $destination_topic->ID );
1341
1342 /** Subscriptions *****************************************************/
1343
1344 // Copy the subscribers
1345 if ( !empty( $_POST['bbp_topic_subscribers'] ) && 1 == $_POST['bbp_topic_subscribers'] && bbp_is_subscriptions_active() ) {
1346
1347 // Get the subscribers
1348 $subscribers = bbp_get_topic_subscribers( $source_topic->ID );
1349
1350 if ( !empty( $subscribers ) ) {
1351
1352 // Add subscribers to new topic
1353 foreach ( (array) $subscribers as $subscriber ) {
1354 bbp_add_user_subscription( $subscriber, $destination_topic->ID );
1355 }
1356 }
1357 }
1358
1359 /** Favorites *********************************************************/
1360
1361 // Copy the favoriters if told to
1362 if ( !empty( $_POST['bbp_topic_favoriters'] ) && 1 == $_POST['bbp_topic_favoriters'] ) {
1363
1364 // Get the favoriters
1365 $favoriters = bbp_get_topic_favoriters( $source_topic->ID );
1366
1367 if ( !empty( $favoriters ) ) {
1368
1369 // Add the favoriters to new topic
1370 foreach ( (array) $favoriters as $favoriter ) {
1371 bbp_add_user_favorite( $favoriter, $destination_topic->ID );
1372 }
1373 }
1374 }
1375
1376 /** Tags **************************************************************/
1377
1378 // Copy the tags if told to
1379 if ( !empty( $_POST['bbp_topic_tags'] ) && ( 1 == $_POST['bbp_topic_tags'] ) ) {
1380
1381 // Get the source topic tags
1382 $source_topic_tags = wp_get_post_terms( $source_topic->ID, bbp_get_topic_tag_tax_id(), array( 'fields' => 'names' ) );
1383
1384 if ( !empty( $source_topic_tags ) ) {
1385 wp_set_post_terms( $destination_topic->ID, $source_topic_tags, bbp_get_topic_tag_tax_id(), true );
1386 }
1387 }
1388
1389 /** Split Replies *************************************************/
1390
1391 // get_posts() is not used because it doesn't allow us to use '>='
1392 // comparision without a filter.
1393 $replies = (array) $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->posts} WHERE {$wpdb->posts}.post_date >= %s AND {$wpdb->posts}.post_parent = %d AND {$wpdb->posts}.post_type = %s ORDER BY {$wpdb->posts}.post_date ASC", $from_reply->post_date, $source_topic->ID, bbp_get_reply_post_type() ) );
1394
1395 // Make sure there are replies to loop through
1396 if ( !empty( $replies ) && !is_wp_error( $replies ) ) {
1397
1398 // Change the post_parent of each reply to the destination topic id
1399 foreach ( $replies as $reply ) {
1400
1401 // New reply data
1402 $postarr = array(
1403 'ID' => $reply->ID,
1404 'post_title' => sprintf( __( 'Reply To: %s', 'bbpress' ), $destination_topic->post_title ),
1405 'post_name' => false, // will be automatically generated
1406 'post_parent' => $destination_topic->ID,
1407 'guid' => ''
1408 );
1409
1410 // Update the reply
1411 wp_update_post( $postarr );
1412
1413 // Adjust reply meta values
1414 bbp_update_reply_topic_id( $reply->ID, $destination_topic->ID );
1415 bbp_update_reply_forum_id( $reply->ID, bbp_get_topic_forum_id( $destination_topic->ID ) );
1416
1417 // Do additional actions per split reply
1418 do_action( 'bbp_split_topic_reply', $reply->ID, $destination_topic->ID );
1419 }
1420 }
1421
1422 // It is a new topic and we need to set some default metas to make
1423 // the topic display in bbp_has_topics() list
1424 if ( 'reply' == $split_option ) {
1425 $last_reply_id = ( empty( $reply ) || empty( $reply->ID ) ) ? 0 : $reply->ID;
1426 $freshness = ( empty( $reply ) || empty( $reply->post_date ) ) ? '' : $reply->post_date;
1427
1428 bbp_update_topic_last_reply_id ( $destination_topic->ID, $last_reply_id );
1429 bbp_update_topic_last_active_time( $destination_topic->ID, $freshness );
1430 }
1431
1432 /** Successful Split **************************************************/
1433
1434 // Update counts, etc...
1435 do_action( 'bbp_post_split_topic', $from_reply->ID, $source_topic->ID, $destination_topic->ID );
1436
1437 // Redirect back to the topic
1438 wp_redirect( bbp_get_topic_permalink( $destination_topic->ID ) );
1439
1440 // For good measure
1441 exit();
1442 }
1443 }
1444
1445 /**
1446 * Fix counts on topic split
1447 *
1448 * When a topic is split, update the counts of source and destination topic
1449 * and their forums.
1450 *
1451 * @since bbPress (r2756)
1452 *
1453 * @param int $from_reply_id From reply id
1454 * @param int $source_topic_id Source topic id
1455 * @param int $destination_topic_id Destination topic id
1456 * @uses bbp_update_forum_topic_count() To update the forum topic counts
1457 * @uses bbp_update_forum_reply_count() To update the forum reply counts
1458 * @uses bbp_update_topic_reply_count() To update the topic reply counts
1459 * @uses bbp_update_topic_voice_count() To update the topic voice counts
1460 * @uses bbp_update_topic_reply_count_hidden() To update the topic hidden reply
1461 * count
1462 * @uses do_action() Calls 'bbp_split_topic_count' with the from reply id,
1463 * source topic id & destination topic id
1464 */
1465 function bbp_split_topic_count( $from_reply_id, $source_topic_id, $destination_topic_id ) {
1466
1467 // Forum Topic Counts
1468 bbp_update_forum_topic_count( $destination_topic_id );
1469
1470 // Forum Reply Counts
1471 bbp_update_forum_reply_count( $destination_topic_id );
1472
1473 // Topic Reply Counts
1474 bbp_update_topic_reply_count( $source_topic_id );
1475 bbp_update_topic_reply_count( $destination_topic_id );
1476
1477 // Topic Hidden Reply Counts
1478 bbp_update_topic_reply_count_hidden( $source_topic_id );
1479 bbp_update_topic_reply_count_hidden( $destination_topic_id );
1480
1481 // Topic Voice Counts
1482 bbp_update_topic_voice_count( $source_topic_id );
1483 bbp_update_topic_voice_count( $destination_topic_id );
1484
1485 do_action( 'bbp_split_topic_count', $from_reply_id, $source_topic_id, $destination_topic_id );
1486 }
1487
1488 /**
1489 * Handles the front end tag management (renaming, merging, destroying)
1490 *
1491 * @since bbPress (r2768)
1492 *
1493 * @uses check_admin_referer() To verify the nonce and check the referer
1494 * @uses current_user_can() To check if the current user can edit/delete tags
1495 * @uses bbPress::errors::add() To log the error messages
1496 * @uses wp_update_term() To update the topic tag
1497 * @uses get_term_link() To get the topic tag url
1498 * @uses term_exists() To check if the topic tag already exists
1499 * @uses wp_insert_term() To insert a topic tag
1500 * @uses wp_delete_term() To delete the topic tag
1501 * @uses home_url() To get the blog's home page url
1502 * @uses do_action() Calls actions based on the actions with associated args
1503 * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
1504 * @uses wp_redirect() To redirect to the url
1505 */
1506 function bbp_manage_topic_tag_handler() {
1507
1508 // Bail if not a POST action
1509 if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
1510 return;
1511
1512 // Bail if required POST actions aren't passed
1513 if ( empty( $_POST['tag-id'] ) || empty( $_POST['action'] ) )
1514 return;
1515
1516 // Setup possible get actions
1517 $possible_actions = array(
1518 'bbp-update-topic-tag',
1519 'bbp-merge-topic-tag',
1520 'bbp-delete-topic-tag'
1521 );
1522
1523 // Bail if actions aren't meant for this function
1524 if ( !in_array( $_POST['action'], $possible_actions ) )
1525 return;
1526
1527 // Setup vars
1528 $action = $_POST['action'];
1529 $tag_id = (int) $_POST['tag-id'];
1530 $tag = get_term( $tag_id, bbp_get_topic_tag_tax_id() );
1531
1532 // Tag does not exist
1533 if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
1534 bbp_add_error( 'bbp_manage_topic_invalid_tag', sprintf( __( '<strong>ERROR</strong>: The following problem(s) have been found while getting the tag: %s', 'bbpress' ), $tag->get_error_message() ) );
1535 return;
1536 }
1537
1538 // What action are we trying to perform?
1539 switch ( $action ) {
1540
1541 // Update tag
1542 case 'bbp-update-topic-tag' :
1543
1544 // Nonce check
1545 check_admin_referer( 'update-tag_' . $tag_id );
1546
1547 // Can user edit topic tags?
1548 if ( !current_user_can( 'edit_topic_tags' ) ) {
1549 bbp_add_error( 'bbp_manage_topic_tag_update_permissions', __( '<strong>ERROR</strong>: You do not have the permissions to edit the topic tags.', 'bbpress' ) );
1550 return;
1551 }
1552
1553 // No tag name was provided
1554 if ( empty( $_POST['tag-name'] ) || !$name = $_POST['tag-name'] ) {
1555 bbp_add_error( 'bbp_manage_topic_tag_update_name', __( '<strong>ERROR</strong>: You need to enter a tag name.', 'bbpress' ) );
1556 return;
1557 }
1558
1559 // Attempt to update the tag
1560 $slug = !empty( $_POST['tag-slug'] ) ? $_POST['tag-slug'] : '';
1561 $tag = wp_update_term( $tag_id, bbp_get_topic_tag_tax_id(), array( 'name' => $name, 'slug' => $slug ) );
1562
1563 // Cannot update tag
1564 if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
1565 bbp_add_error( 'bbp_manage_topic_tag_update_error', sprintf( __( '<strong>ERROR</strong>: The following problem(s) have been found while updating the tag: %s', 'bbpress' ), $tag->get_error_message() ) );
1566 return;
1567 }
1568
1569 // Redirect
1570 $redirect = get_term_link( $tag_id, bbp_get_topic_tag_tax_id() );
1571
1572 // Update counts, etc...
1573 do_action( 'bbp_update_topic_tag', $tag_id, $tag, $name, $slug );
1574
1575 break;
1576
1577 // Merge two tags
1578 case 'bbp-merge-topic-tag' :
1579
1580 // Nonce check
1581 check_admin_referer( 'merge-tag_' . $tag_id );
1582
1583 // Can user edit topic tags?
1584 if ( !current_user_can( 'edit_topic_tags' ) ) {
1585 bbp_add_error( 'bbp_manage_topic_tag_merge_permissions', __( '<strong>ERROR</strong>: You do not have the permissions to edit the topic tags.', 'bbpress' ) );
1586 return;
1587 }
1588
1589 // No tag name was provided
1590 if ( empty( $_POST['tag-existing-name'] ) || !$name = $_POST['tag-existing-name'] ) {
1591 bbp_add_error( 'bbp_manage_topic_tag_merge_name', __( '<strong>ERROR</strong>: You need to enter a tag name.', 'bbpress' ) );
1592 return;
1593 }
1594
1595 // If term does not exist, create it
1596 if ( !$tag = term_exists( $name, bbp_get_topic_tag_tax_id() ) )
1597 $tag = wp_insert_term( $name, bbp_get_topic_tag_tax_id() );
1598
1599 // Problem inserting the new term
1600 if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
1601 bbp_add_error( 'bbp_manage_topic_tag_merge_error', sprintf( __( '<strong>ERROR</strong>: The following problem(s) have been found while merging the tags: %s', 'bbpress' ), $tag->get_error_message() ) );
1602 return;
1603 }
1604
1605 // Merging in to...
1606 $to_tag = $tag['term_id'];
1607
1608 // Attempting to merge a tag into itself
1609 if ( $tag_id == $to_tag ) {
1610 bbp_add_error( 'bbp_manage_topic_tag_merge_same', __( '<strong>ERROR</strong>: The tags which are being merged can not be the same.', 'bbpress' ) );
1611 return;
1612 }
1613
1614 // Delete the old term
1615 $tag = wp_delete_term( $tag_id, bbp_get_topic_tag_tax_id(), array( 'default' => $to_tag, 'force_default' => true ) );
1616
1617 // Error merging the terms
1618 if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
1619 bbp_add_error( 'bbp_manage_topic_tag_merge_error', sprintf( __( '<strong>ERROR</strong>: The following problem(s) have been found while merging the tags: %s', 'bbpress' ), $tag->get_error_message() ) );
1620 return;
1621 }
1622
1623 // Redirect
1624 $redirect = get_term_link( (int) $to_tag, bbp_get_topic_tag_tax_id() );
1625
1626 // Update counts, etc...
1627 do_action( 'bbp_merge_topic_tag', $tag_id, $to_tag, $tag );
1628
1629 break;
1630
1631 // Delete tag
1632 case 'bbp-delete-topic-tag' :
1633
1634 // Nonce check
1635 check_admin_referer( 'delete-tag_' . $tag_id );
1636
1637 // Can user delete topic tags?
1638 if ( !current_user_can( 'delete_topic_tags' ) ) {
1639 bbp_add_error( 'bbp_manage_topic_tag_delete_permissions', __( '<strong>ERROR</strong>: You do not have the permissions to delete the topic tags.', 'bbpress' ) );
1640 return;
1641 }
1642
1643 // Attempt to delete term
1644 $tag = wp_delete_term( $tag_id, bbp_get_topic_tag_tax_id() );
1645
1646 // Error deleting term
1647 if ( is_wp_error( $tag ) && $tag->get_error_message() ) {
1648 bbp_add_error( 'bbp_manage_topic_tag_delete_error', sprintf( __( '<strong>ERROR</strong>: The following problem(s) have been found while deleting the tag: %s', 'bbpress' ), $tag->get_error_message() ) );
1649 return;
1650 }
1651
1652 // We don't have any other place to go other than home! Or we may die because of the 404 disease
1653 $redirect = home_url();
1654
1655 // Update counts, etc...
1656 do_action( 'bbp_delete_topic_tag', $tag_id, $tag );
1657
1658 break;
1659 }
1660
1661 /** Successful Moderation *************************************************/
1662
1663 // Redirect back
1664 $redirect = ( !empty( $redirect ) && !is_wp_error( $redirect ) ) ? $redirect : home_url();
1665 wp_safe_redirect( $redirect );
1666
1667 // For good measure
1668 exit();
1669 }
1670
1671 /** Stickies ******************************************************************/
1672
1673 /**
1674 * Return sticky topics of a forum
1675 *
1676 * @since bbPress (r2592)
1677 *
1678 * @param int $forum_id Optional. If not passed, super stickies are returned.
1679 * @uses bbp_get_super_stickies() To get the super stickies
1680 * @uses get_post_meta() To get the forum stickies
1681 * @uses apply_filters() Calls 'bbp_get_stickies' with the stickies and forum id
1682 * @return array IDs of sticky topics of a forum or super stickies
1683 */
1684 function bbp_get_stickies( $forum_id = 0 ) {
1685 $stickies = empty( $forum_id ) ? bbp_get_super_stickies() : get_post_meta( $forum_id, '_bbp_sticky_topics', true );
1686 $stickies = ( empty( $stickies ) || !is_array( $stickies ) ) ? array() : $stickies;
1687
1688 return apply_filters( 'bbp_get_stickies', $stickies, (int) $forum_id );
1689 }
1690
1691 /**
1692 * Return topics stuck to front page of the forums
1693 *
1694 * @since bbPress (r2592)
1695 *
1696 * @uses get_option() To get super sticky topics
1697 * @uses apply_filters() Calls 'bbp_get_super_stickies' with the stickies
1698 * @return array IDs of super sticky topics
1699 */
1700 function bbp_get_super_stickies() {
1701 $stickies = get_option( '_bbp_super_sticky_topics', array() );
1702 $stickies = ( empty( $stickies ) || !is_array( $stickies ) ) ? array() : $stickies;
1703
1704 return apply_filters( 'bbp_get_super_stickies', $stickies );
1705 }
1706
1707 /** Topics Actions ************************************************************/
1708
1709 /**
1710 * Handles the front end opening/closing, spamming/unspamming,
1711 * sticking/unsticking and trashing/untrashing/deleting of topics
1712 *
1713 * @since bbPress (r2727)
1714 *
1715 * @uses bbp_get_topic() To get the topic
1716 * @uses current_user_can() To check if the user is capable of editing or
1717 * deleting the topic
1718 * @uses bbp_get_topic_post_type() To get the topic post type
1719 * @uses check_ajax_referer() To verify the nonce and check the referer
1720 * @uses bbp_is_topic_open() To check if the topic is open
1721 * @uses bbp_close_topic() To close the topic
1722 * @uses bbp_open_topic() To open the topic
1723 * @uses bbp_is_topic_sticky() To check if the topic is a sticky
1724 * @uses bbp_unstick_topic() To unstick the topic
1725 * @uses bbp_stick_topic() To stick the topic
1726 * @uses bbp_is_topic_spam() To check if the topic is marked as spam
1727 * @uses bbp_spam_topic() To make the topic as spam
1728 * @uses bbp_unspam_topic() To unmark the topic as spam
1729 * @uses wp_trash_post() To trash the topic
1730 * @uses wp_untrash_post() To untrash the topic
1731 * @uses wp_delete_post() To delete the topic
1732 * @uses do_action() Calls 'bbp_toggle_topic_handler' with success, post data
1733 * and action
1734 * @uses bbp_get_forum_permalink() To get the forum link
1735 * @uses bbp_get_topic_permalink() To get the topic link
1736 * @uses add_query_arg() To add args to the url
1737 * @uses wp_redirect() To redirect to the topic
1738 * @uses bbPress::errors:add() To log the error messages
1739 */
1740 function bbp_toggle_topic_handler() {
1741
1742 // Bail if not a GET action
1743 if ( 'GET' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
1744 return;
1745
1746 // Bail if required GET actions aren't passed
1747 if ( empty( $_GET['topic_id'] ) || empty( $_GET['action'] ) )
1748 return;
1749
1750 // Setup possible get actions
1751 $possible_actions = array(
1752 'bbp_toggle_topic_close',
1753 'bbp_toggle_topic_stick',
1754 'bbp_toggle_topic_spam',
1755 'bbp_toggle_topic_trash'
1756 );
1757
1758 // Bail if actions aren't meant for this function
1759 if ( !in_array( $_GET['action'], $possible_actions ) )
1760 return;
1761
1762 $view_all = false; // Assume not viewing all
1763 $action = $_GET['action']; // What action is taking place?
1764 $topic_id = (int) $_GET['topic_id']; // What's the topic id?
1765 $success = false; // Flag
1766 $post_data = array( 'ID' => $topic_id ); // Prelim array
1767
1768 // Make sure topic exists
1769 if ( !$topic = bbp_get_topic( $topic_id ) )
1770 return;
1771
1772 // What is the user doing here?
1773 if ( !current_user_can( 'edit_topic', $topic->ID ) || ( 'bbp_toggle_topic_trash' == $action && !current_user_can( 'delete_topic', $topic->ID ) ) ) {
1774 bbp_add_error( 'bbp_toggle_topic_permission', __( '<strong>ERROR:</strong> You do not have the permission to do that.', 'bbpress' ) );
1775 return;
1776 }
1777
1778 // What action are we trying to perform?
1779 switch ( $action ) {
1780
1781 // Toggle open/close
1782 case 'bbp_toggle_topic_close' :
1783 check_ajax_referer( 'close-topic_' . $topic_id );
1784
1785 $is_open = bbp_is_topic_open( $topic_id );
1786 $success = $is_open ? bbp_close_topic( $topic_id ) : bbp_open_topic( $topic_id );
1787 $failure = $is_open ? __( '<strong>ERROR</strong>: There was a problem closing the topic.', 'bbpress' ) : __( '<strong>ERROR</strong>: There was a problem opening the topic.', 'bbpress' );
1788
1789 break;
1790
1791 // Toggle sticky/super-sticky/unstick
1792 case 'bbp_toggle_topic_stick' :
1793 check_ajax_referer( 'stick-topic_' . $topic_id );
1794
1795 $is_sticky = bbp_is_topic_sticky( $topic_id );
1796 $is_super = ( empty( $is_sticky ) && !empty( $_GET['super'] ) && 1 == (int) $_GET['super'] ) ? true : false;
1797 $success = $is_sticky ? bbp_unstick_topic( $topic_id ) : bbp_stick_topic( $topic_id, $is_super );
1798 $failure = $is_sticky ? __( '<strong>ERROR</strong>: There was a problem unsticking the topic.', 'bbpress' ) : __( '<strong>ERROR</strong>: There was a problem sticking the topic.', 'bbpress' );
1799
1800 break;
1801
1802 // Toggle spam
1803 case 'bbp_toggle_topic_spam' :
1804 check_ajax_referer( 'spam-topic_' . $topic_id );
1805
1806 $is_spam = bbp_is_topic_spam( $topic_id );
1807 $success = $is_spam ? bbp_unspam_topic( $topic_id ) : bbp_spam_topic( $topic_id );
1808 $failure = $is_spam ? __( '<strong>ERROR</strong>: There was a problem unmarking the topic as spam.', 'bbpress' ) : __( '<strong>ERROR</strong>: There was a problem marking the topic as spam.', 'bbpress' );
1809 $view_all = !$is_spam;
1810
1811 break;
1812
1813 // Toggle trash
1814 case 'bbp_toggle_topic_trash' :
1815
1816 $sub_action = in_array( $_GET['sub_action'], array( 'trash', 'untrash', 'delete' ) ) ? $_GET['sub_action'] : false;
1817
1818 if ( empty( $sub_action ) )
1819 break;
1820
1821 switch ( $sub_action ) {
1822 case 'trash':
1823 check_ajax_referer( 'trash-' . bbp_get_topic_post_type() . '_' . $topic_id );
1824
1825 $view_all = true;
1826 $success = wp_trash_post( $topic_id );
1827 $failure = __( '<strong>ERROR</strong>: There was a problem trashing the topic.', 'bbpress' );
1828
1829 break;
1830
1831 case 'untrash':
1832 check_ajax_referer( 'untrash-' . bbp_get_topic_post_type() . '_' . $topic_id );
1833
1834 $success = wp_untrash_post( $topic_id );
1835 $failure = __( '<strong>ERROR</strong>: There was a problem untrashing the topic.', 'bbpress' );
1836
1837 break;
1838
1839 case 'delete':
1840 check_ajax_referer( 'delete-' . bbp_get_topic_post_type() . '_' . $topic_id );
1841
1842 $success = wp_delete_post( $topic_id );
1843 $failure = __( '<strong>ERROR</strong>: There was a problem deleting the topic.', 'bbpress' );
1844
1845 break;
1846 }
1847
1848 break;
1849 }
1850
1851 // Do additional topic toggle actions
1852 do_action( 'bbp_toggle_topic_handler', $success, $post_data, $action );
1853
1854 // No errors
1855 if ( false != $success && !is_wp_error( $success ) ) {
1856
1857 // Redirect back to the topic's forum
1858 if ( isset( $sub_action ) && ( 'delete' == $sub_action ) ) {
1859 $redirect = bbp_get_forum_permalink( $success->post_parent );
1860
1861 // Redirect back to the topic
1862 } else {
1863
1864 // Get the redirect detination
1865 $permalink = bbp_get_topic_permalink( $topic_id );
1866 $redirect = bbp_add_view_all( $permalink, $view_all );
1867 }
1868
1869 wp_redirect( $redirect );
1870
1871 // For good measure
1872 exit();
1873
1874 // Handle errors
1875 } else {
1876 bbp_add_error( 'bbp_toggle_topic', $failure );
1877 }
1878 }
1879
1880 /** Favorites & Subscriptions *************************************************/
1881
1882 /**
1883 * Remove a deleted topic from all users' favorites
1884 *
1885 * @since bbPress (r2652)
1886 *
1887 * @param int $topic_id Topic ID to remove
1888 * @uses bbp_get_topic_favoriters() To get the topic's favoriters
1889 * @uses bbp_remove_user_favorite() To remove the topic from user's favorites
1890 */
1891 function bbp_remove_topic_from_all_favorites( $topic_id = 0 ) {
1892 $topic_id = bbp_get_topic_id( $topic_id );
1893
1894 // Bail if no topic
1895 if ( empty( $topic_id ) )
1896 return;
1897
1898 // Get users
1899 $users = (array) bbp_get_topic_favoriters( $topic_id );
1900
1901 // Users exist
1902 if ( !empty( $users ) ) {
1903
1904 // Loop through users
1905 foreach ( $users as $user ) {
1906
1907 // Remove each user
1908 bbp_remove_user_favorite( $user, $topic_id );
1909 }
1910 }
1911 }
1912
1913 /**
1914 * Remove a deleted topic from all users' subscriptions
1915 *
1916 * @since bbPress (r2652)
1917 *
1918 * @param int $topic_id Topic ID to remove
1919 * @uses bbp_is_subscriptions_active() To check if the subscriptions are active
1920 * @uses bbp_get_topic_subscribers() To get the topic subscribers
1921 * @uses bbp_remove_user_subscription() To remove the user subscription
1922 */
1923 function bbp_remove_topic_from_all_subscriptions( $topic_id = 0 ) {
1924
1925 // Subscriptions are not active
1926 if ( !bbp_is_subscriptions_active() )
1927 return;
1928
1929 $topic_id = bbp_get_topic_id( $topic_id );
1930
1931 // Bail if no topic
1932 if ( empty( $topic_id ) )
1933 return;
1934
1935 // Get users
1936 $users = (array) bbp_get_topic_subscribers( $topic_id );
1937
1938 // Users exist
1939 if ( !empty( $users ) ) {
1940
1941 // Loop through users
1942 foreach ( $users as $user ) {
1943
1944 // Remove each user
1945 bbp_remove_user_subscription( $user, $topic_id );
1946 }
1947 }
1948 }
1949
1950 /** Topic Updaters ************************************************************/
1951
1952 /**
1953 * Update the topic's forum id
1954 *
1955 * @since bbPress (r2855)
1956 *
1957 * @param int $topic_id Optional. Topic id to update
1958 * @param int $forum_id Optional. Forum id
1959 * @uses bbp_is_reply() TO check if the passed topic id is a reply
1960 * @uses bbp_get_reply_topic_id() To get the reply topic id
1961 * @uses bbp_get_topic_id() To get the topic id
1962 * @uses get_post_field() To get the post parent of the topic id
1963 * @uses bbp_get_forum_id() To get the forum id
1964 * @uses update_post_meta() To update the topic forum id meta
1965 * @uses apply_filters() Calls 'bbp_update_topic_forum_id' with the forum id
1966 * and topic id
1967 * @return int Forum id
1968 */
1969 function bbp_update_topic_forum_id( $topic_id = 0, $forum_id = 0 ) {
1970
1971 // If it's a reply, then get the parent (topic id)
1972 if ( bbp_is_reply( $topic_id ) )
1973 $topic_id = bbp_get_reply_topic_id( $topic_id );
1974 else
1975 $topic_id = bbp_get_topic_id( $topic_id );
1976
1977 if ( empty( $forum_id ) )
1978 $forum_id = get_post_field( 'post_parent', $topic_id );
1979
1980 update_post_meta( $topic_id, '_bbp_forum_id', (int) $forum_id );
1981
1982 return apply_filters( 'bbp_update_topic_forum_id', (int) $forum_id, $topic_id );
1983 }
1984
1985 /**
1986 * Update the topic's topic id
1987 *
1988 * @since bbPress (r2954)
1989 *
1990 * @param int $topic_id Optional. Topic id to update
1991 * @uses bbp_get_topic_id() To get the topic id
1992 * @uses update_post_meta() To update the topic's topic id meta
1993 * @uses apply_filters() Calls 'bbp_update_topic_topic_id' with the topic id
1994 * @return int Topic id
1995 */
1996 function bbp_update_topic_topic_id( $topic_id = 0 ) {
1997 $topic_id = bbp_get_topic_id( $topic_id );
1998
1999 update_post_meta( $topic_id, '_bbp_topic_id', (int) $topic_id );
2000
2001 return apply_filters( 'bbp_update_topic_topic_id', (int) $topic_id );
2002 }
2003
2004 /**
2005 * Adjust the total reply count of a topic
2006 *
2007 * @since bbPress (r2467)
2008 *
2009 * @param int $topic_id Optional. Topic id to update
2010 * @param int $reply_count Optional. Set the reply count manually.
2011 * @uses bbp_is_reply() To check if the passed topic id is a reply
2012 * @uses bbp_get_reply_topic_id() To get the reply topic id
2013 * @uses bbp_get_topic_id() To get the topic id
2014 * @uses bbp_get_reply_post_type() To get the reply post type
2015 * @uses bbp_get_public_child_count() To get the reply count
2016 * @uses update_post_meta() To update the topic reply count meta
2017 * @uses apply_filters() Calls 'bbp_update_topic_reply_count' with the reply
2018 * count and topic id
2019 * @return int Topic reply count
2020 */
2021 function bbp_update_topic_reply_count( $topic_id = 0, $reply_count = 0 ) {
2022
2023 // If it's a reply, then get the parent (topic id)
2024 if ( bbp_is_reply( $topic_id ) )
2025 $topic_id = bbp_get_reply_topic_id( $topic_id );
2026 else
2027 $topic_id = bbp_get_topic_id( $topic_id );
2028
2029 // Get replies of topic if not passed
2030 if ( empty( $reply_count ) )
2031 $reply_count = bbp_get_public_child_count( $topic_id, bbp_get_reply_post_type() );
2032
2033 update_post_meta( $topic_id, '_bbp_reply_count', (int) $reply_count );
2034
2035 return apply_filters( 'bbp_update_topic_reply_count', (int) $reply_count, $topic_id );
2036 }
2037
2038 /**
2039 * Adjust the total hidden reply count of a topic (hidden includes trashed and spammed replies)
2040 *
2041 * @since bbPress (r2740)
2042 *
2043 * @param int $topic_id Optional. Topic id to update
2044 * @param int $reply_count Optional. Set the reply count manually
2045 * @uses bbp_is_reply() To check if the passed topic id is a reply
2046 * @uses bbp_get_reply_topic_id() To get the reply topic id
2047 * @uses bbp_get_topic_id() To get the topic id
2048 * @uses bbp_get_reply_post_type() To get the reply post type
2049 * @uses wpdb::prepare() To prepare our sql query
2050 * @uses wpdb::get_var() To execute our query and get the var back
2051 * @uses update_post_meta() To update the topic hidden reply count meta
2052 * @uses apply_filters() Calls 'bbp_update_topic_reply_count_hidden' with the
2053 * hidden reply count and topic id
2054 * @return int Topic hidden reply count
2055 */
2056 function bbp_update_topic_reply_count_hidden( $topic_id = 0, $reply_count = 0 ) {
2057 global $wpdb, $bbp;
2058
2059 // If it's a reply, then get the parent (topic id)
2060 if ( bbp_is_reply( $topic_id ) )
2061 $topic_id = bbp_get_reply_topic_id( $topic_id );
2062 else
2063 $topic_id = bbp_get_topic_id( $topic_id );
2064
2065 // Get replies of topic
2066 if ( empty( $reply_count ) )
2067 $reply_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';", $topic_id, bbp_get_reply_post_type() ) );
2068
2069 update_post_meta( $topic_id, '_bbp_reply_count_hidden', (int) $reply_count );
2070
2071 return apply_filters( 'bbp_update_topic_reply_count_hidden', (int) $reply_count, $topic_id );
2072 }
2073
2074 /**
2075 * Update the topic with the last active post ID
2076 *
2077 * @since bbPress (r2888)
2078 *
2079 * @param int $topic_id Optional. Topic id to update
2080 * @param int $active_id Optional. active id
2081 * @uses bbp_is_reply() To check if the passed topic id is a reply
2082 * @uses bbp_get_reply_topic_id() To get the reply topic id
2083 * @uses bbp_get_topic_id() To get the topic id
2084 * @uses bbp_get_reply_post_type() To get the reply post type
2085 * @uses bbp_get_public_child_last_id() To get the last public reply id
2086 * @uses bbp_get_active_id() To get the active id
2087 * @uses update_post_meta() To update the topic last active id meta
2088 * @uses apply_filters() Calls 'bbp_update_topic_last_active_id' with the active
2089 * id and topic id
2090 * @return int Active id
2091 */
2092 function bbp_update_topic_last_active_id( $topic_id = 0, $active_id = 0 ) {
2093
2094 // If it's a reply, then get the parent (topic id)
2095 if ( bbp_is_reply( $topic_id ) )
2096 $topic_id = bbp_get_reply_topic_id( $topic_id );
2097 else
2098 $topic_id = bbp_get_topic_id( $topic_id );
2099
2100 if ( empty( $active_id ) )
2101 $active_id = bbp_get_public_child_last_id( $topic_id, bbp_get_reply_post_type() );
2102
2103 // Adjust last_id's based on last_reply post_type
2104 if ( empty( $active_id ) || !bbp_is_reply( $active_id ) )
2105 $active_id = $topic_id;
2106
2107 update_post_meta( $topic_id, '_bbp_last_active_id', (int) $active_id );
2108
2109 return apply_filters( 'bbp_update_topic_last_active_id', (int) $active_id, $topic_id );
2110 }
2111
2112 /**
2113 * Update the topics last active date/time (aka freshness)
2114 *
2115 * @since bbPress (r2680)
2116 *
2117 * @param int $topic_id Optional. Topic id
2118 * @param string $new_time Optional. New time in mysql format
2119 * @uses bbp_get_topic_id() To get the topic id
2120 * @uses bbp_get_reply_topic_id() To get the reply topic id
2121 * @uses current_time() To get the current time
2122 * @uses update_post_meta() To update the topic last active meta
2123 * @return bool True on success, false on failure
2124 */
2125 function bbp_update_topic_last_active_time( $topic_id = 0, $new_time = '' ) {
2126
2127 // If it's a reply, then get the parent (topic id)
2128 if ( bbp_is_reply( $topic_id ) )
2129 $topic_id = bbp_get_reply_topic_id( $topic_id );
2130 else
2131 $topic_id = bbp_get_topic_id( $topic_id );
2132
2133 // Check time and use current if empty
2134 if ( empty( $new_time ) )
2135 $new_time = get_post_field( 'post_date', bbp_get_public_child_last_id( $topic_id, bbp_get_reply_post_type() ) );
2136
2137 update_post_meta( $topic_id, '_bbp_last_active_time', $new_time );
2138
2139 return apply_filters( 'bbp_update_topic_last_active_time', $new_time, $topic_id );
2140 }
2141
2142 /**
2143 * Update the topic with the most recent reply ID
2144 *
2145 * @since bbPress (r2625)
2146 *
2147 * @param int $topic_id Optional. Topic id to update
2148 * @param int $reply_id Optional. Reply id
2149 * @uses bbp_is_reply() To check if the passed topic id is a reply
2150 * @uses bbp_get_reply_id() To get the reply id
2151 * @uses bbp_get_reply_topic_id() To get the reply topic id
2152 * @uses bbp_get_topic_id() To get the topic id
2153 * @uses bbp_get_reply_post_type() To get the reply post type
2154 * @uses bbp_get_public_child_last_id() To get the last public reply id
2155 * @uses update_post_meta() To update the topic last reply id meta
2156 * @uses apply_filters() Calls 'bbp_update_topic_last_reply_id' with the reply
2157 * id and topic id
2158 * @return int Reply id
2159 */
2160 function bbp_update_topic_last_reply_id( $topic_id = 0, $reply_id = 0 ) {
2161
2162 // If it's a reply, then get the parent (topic id)
2163 if ( empty( $reply_id ) && bbp_is_reply( $topic_id ) ) {
2164 $reply_id = bbp_get_reply_id( $topic_id );
2165 $topic_id = bbp_get_reply_topic_id( $reply_id );
2166 } else {
2167 $reply_id = bbp_get_reply_id( $reply_id );
2168 $topic_id = bbp_get_topic_id( $topic_id );
2169 }
2170
2171 if ( empty( $reply_id ) )
2172 $reply_id = bbp_get_public_child_last_id( $topic_id, bbp_get_reply_post_type() );
2173
2174 // Adjust last_id's based on last_reply post_type
2175 if ( empty( $reply_id ) || !bbp_is_reply( $reply_id ) )
2176 $reply_id = 0;
2177
2178 update_post_meta( $topic_id, '_bbp_last_reply_id', (int) $reply_id );
2179
2180 return apply_filters( 'bbp_update_topic_last_reply_id', (int) $reply_id, $topic_id );
2181 }
2182
2183 /**
2184 * Adjust the total voice count of a topic
2185 *
2186 * @since bbPress (r2567)
2187 *
2188 * @param int $topic_id Optional. Topic id to update
2189 * @uses bbp_is_reply() To check if the passed topic id is a reply
2190 * @uses bbp_get_reply_topic_id() To get the reply topic id
2191 * @uses bbp_get_topic_id() To get the topic id
2192 * @uses bbp_get_reply_topic_id() To get the reply topic id
2193 * @uses bbp_get_reply_post_type() To get the reply post type
2194 * @uses bbp_get_topic_post_type() To get the topic post type
2195 * @uses wpdb::prepare() To prepare our sql query
2196 * @uses wpdb::get_col() To execute our query and get the column back
2197 * @uses update_post_meta() To update the topic voice count meta
2198 * @uses apply_filters() Calls 'bbp_update_topic_voice_count' with the voice
2199 * count and topic id
2200 * @return int Voice count
2201 */
2202 function bbp_update_topic_voice_count( $topic_id = 0 ) {
2203 global $wpdb;
2204
2205 // If it's a reply, then get the parent (topic id)
2206 if ( bbp_is_reply( $topic_id ) )
2207 $topic_id = bbp_get_reply_topic_id( $topic_id );
2208 elseif ( bbp_is_topic( $topic_id ) )
2209 $topic_id = bbp_get_topic_id( $topic_id );
2210 else
2211 return;
2212
2213 // Query the DB to get voices in this topic
2214 $voices = $wpdb->get_col( $wpdb->prepare( "SELECT COUNT( DISTINCT post_author ) FROM {$wpdb->posts} WHERE ( post_parent = %d AND post_status = 'publish' AND post_type = '%s' ) OR ( ID = %d AND post_type = '%s' );", $topic_id, bbp_get_reply_post_type(), $topic_id, bbp_get_topic_post_type() ) );
2215
2216 // If there's an error, make sure we at least have 1 voice
2217 $voices = ( empty( $voices ) || is_wp_error( $voices ) ) ? 1 : $voices[0];
2218
2219 // Update the voice count for this topic id
2220 update_post_meta( $topic_id, '_bbp_voice_count', (int) $voices );
2221
2222 return apply_filters( 'bbp_update_topic_voice_count', (int) $voices, $topic_id );
2223 }
2224
2225 /**
2226 * Adjust the total anonymous reply count of a topic
2227 *
2228 * @since bbPress (r2567)
2229 *
2230 * @param int $topic_id Optional. Topic id to update
2231 * @uses bbp_is_reply() To check if the passed topic id is a reply
2232 * @uses bbp_get_reply_topic_id() To get the reply topic id
2233 * @uses bbp_get_topic_id() To get the topic id
2234 * @uses bbp_get_reply_topic_id() To get the reply topic id
2235 * @uses bbp_get_reply_post_type() To get the reply post type
2236 * @uses bbp_get_topic_post_type() To get the topic post type
2237 * @uses wpdb::prepare() To prepare our sql query
2238 * @uses wpdb::get_col() To execute our query and get the column back
2239 * @uses update_post_meta() To update the topic anonymous reply count meta
2240 * @uses apply_filters() Calls 'bbp_update_topic_anonymous_reply_count' with the
2241 * anonymous reply count and topic id
2242 * @return int Anonymous reply count
2243 */
2244 function bbp_update_topic_anonymous_reply_count( $topic_id = 0 ) {
2245 global $wpdb;
2246
2247 // If it's a reply, then get the parent (topic id)
2248 if ( bbp_is_reply( $topic_id ) )
2249 $topic_id = bbp_get_reply_topic_id( $topic_id );
2250 elseif ( bbp_is_topic( $topic_id ) )
2251 $topic_id = bbp_get_topic_id( $topic_id );
2252 else
2253 return;
2254
2255 $anonymous_replies = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( ID ) FROM {$wpdb->posts} WHERE ( post_parent = %d AND post_status = 'publish' AND post_type = '%s' AND post_author = 0 ) OR ( ID = %d AND post_type = '%s' AND post_author = 0 );", $topic_id, bbp_get_reply_post_type(), $topic_id, bbp_get_topic_post_type() ) );
2256
2257 update_post_meta( $topic_id, '_bbp_anonymous_reply_count', (int) $anonymous_replies );
2258
2259 return apply_filters( 'bbp_update_topic_anonymous_reply_count', (int) $anonymous_replies, $topic_id );
2260 }
2261
2262 /**
2263 * Update the revision log of the topic
2264 *
2265 * @since bbPress (r2782)
2266 *
2267 * @param mixed $args Supports these args:
2268 * - topic_id: Topic id
2269 * - author_id: Author id
2270 * - reason: Reason for editing
2271 * - revision_id: Revision id
2272 * @uses bbp_get_topic_id() To get the topic id
2273 * @uses bbp_get_user_id() To get the user id
2274 * @uses bbp_format_revision_reason() To format the reason
2275 * @uses bbp_get_topic_raw_revision_log() To get the raw topic revision log
2276 * @uses update_post_meta() To update the topic revision log meta
2277 * @return mixed False on failure, true on success
2278 */
2279 function bbp_update_topic_revision_log( $args = '' ) {
2280 $defaults = array (
2281 'reason' => '',
2282 'topic_id' => 0,
2283 'author_id' => 0,
2284 'revision_id' => 0
2285 );
2286
2287 $r = wp_parse_args( $args, $defaults );
2288 extract( $r );
2289
2290 // Populate the variables
2291 $reason = bbp_format_revision_reason( $reason );
2292 $topic_id = bbp_get_topic_id( $topic_id );
2293 $author_id = bbp_get_user_id ( $author_id, false, true );
2294 $revision_id = (int) $revision_id;
2295
2296 // Get the logs and append the new one to those
2297 $revision_log = bbp_get_topic_raw_revision_log( $topic_id );
2298 $revision_log[$revision_id] = array( 'author' => $author_id, 'reason' => $reason );
2299
2300 // Finally, update
2301 return update_post_meta( $topic_id, '_bbp_revision_log', $revision_log );
2302 }
2303
2304 /** Topic Actions *************************************************************/
2305
2306 /**
2307 * Closes a topic
2308 *
2309 * @since bbPress (r2740)
2310 *
2311 * @param int $topic_id Topic id
2312 * @uses wp_get_single_post() To get the topic
2313 * @uses do_action() Calls 'bbp_close_topic' with the topic id
2314 * @uses add_post_meta() To add the previous status to a meta
2315 * @uses wp_insert_post() To update the topic with the new status
2316 * @uses do_action() Calls 'bbp_opened_topic' with the topic id
2317 * @return mixed False or {@link WP_Error} on failure, topic id on success
2318 */
2319 function bbp_close_topic( $topic_id = 0 ) {
2320 global $bbp;
2321
2322 // Get topic
2323 if ( !$topic = wp_get_single_post( $topic_id, ARRAY_A ) )
2324 return $topic;
2325
2326 // Bail if already closed
2327 if ( $topic['post_status'] == $bbp->closed_status_id )
2328 return false;
2329
2330 // Execute pre close code
2331 do_action( 'bbp_close_topic', $topic_id );
2332
2333 // Add pre close status
2334 add_post_meta( $topic_id, '_bbp_status', $topic['post_status'] );
2335
2336 // Set closed status
2337 $topic['post_status'] = $bbp->closed_status_id;
2338
2339 // No revisions
2340 remove_action( 'pre_post_update', 'wp_save_post_revision' );
2341
2342 // Update topic
2343 $topic_id = wp_insert_post( $topic );
2344
2345 // Execute post close code
2346 do_action( 'bbp_closed_topic', $topic_id );
2347
2348 // Return topic_id
2349 return $topic_id;
2350 }
2351
2352 /**
2353 * Opens a topic
2354 *
2355 * @since bbPress (r2740)
2356 *
2357 * @param int $topic_id Topic id
2358 * @uses wp_get_single_post() To get the topic
2359 * @uses do_action() Calls 'bbp_open_topic' with the topic id
2360 * @uses get_post_meta() To get the previous status
2361 * @uses delete_post_meta() To delete the previous status meta
2362 * @uses wp_insert_post() To update the topic with the new status
2363 * @uses do_action() Calls 'bbp_opened_topic' with the topic id
2364 * @return mixed False or {@link WP_Error} on failure, topic id on success
2365 */
2366 function bbp_open_topic( $topic_id = 0 ) {
2367 global $bbp;
2368
2369 // Get topic
2370 if ( !$topic = wp_get_single_post( $topic_id, ARRAY_A ) )
2371 return $topic;
2372
2373 // Bail if already open
2374 if ( $topic['post_status'] != $bbp->closed_status_id )
2375 return false;
2376
2377 // Execute pre open code
2378 do_action( 'bbp_open_topic', $topic_id );
2379
2380 // Get previous status
2381 $topic_status = get_post_meta( $topic_id, '_bbp_status', true );
2382
2383 // Set previous status
2384 $topic['post_status'] = $topic_status;
2385
2386 // Remove old status meta
2387 delete_post_meta( $topic_id, '_bbp_status' );
2388
2389 // No revisions
2390 remove_action( 'pre_post_update', 'wp_save_post_revision' );
2391
2392 // Update topic
2393 $topic_id = wp_insert_post( $topic );
2394
2395 // Execute post open code
2396 do_action( 'bbp_opened_topic', $topic_id );
2397
2398 // Return topic_id
2399 return $topic_id;
2400 }
2401
2402 /**
2403 * Marks a topic as spam
2404 *
2405 * @since bbPress (r2740)
2406 *
2407 * @param int $topic_id Topic id
2408 * @uses wp_get_single_post() To get the topic
2409 * @uses do_action() Calls 'bbp_spam_topic' with the topic id
2410 * @uses add_post_meta() To add the previous status to a meta
2411 * @uses wp_insert_post() To update the topic with the new status
2412 * @uses do_action() Calls 'bbp_spammed_topic' with the topic id
2413 * @return mixed False or {@link WP_Error} on failure, topic id on success
2414 */
2415 function bbp_spam_topic( $topic_id = 0 ) {
2416 global $bbp;
2417
2418 // Get the topic
2419 if ( !$topic = wp_get_single_post( $topic_id, ARRAY_A ) )
2420 return $topic;
2421
2422 // Bail if topic is spam
2423 if ( $topic['post_status'] == $bbp->spam_status_id )
2424 return false;
2425
2426 // Execute pre spam code
2427 do_action( 'bbp_spam_topic', $topic_id );
2428
2429 // Add the original post status as post meta for future restoration
2430 add_post_meta( $topic_id, '_bbp_spam_meta_status', $topic['post_status'] );
2431
2432 // Get topic tags
2433 $terms = get_the_terms( $topic_id, bbp_get_topic_tag_tax_id() );
2434
2435 // Topic has tags
2436 if ( !empty( $terms ) ) {
2437
2438 // Loop through and collect term names
2439 foreach( $terms as $term ) {
2440 $term_names[] = $term->name;
2441 }
2442
2443 // Topic terms have slugs
2444 if ( !empty( $term_names ) ) {
2445
2446 // Add the original post status as post meta for future restoration
2447 add_post_meta( $topic_id, '_bbp_spam_topic_tags', $term_names );
2448
2449 // Empty the topic of its tags
2450 $topic['tax_input'] = array( bbp_get_topic_tag_tax_id() => '' );
2451 }
2452 }
2453
2454 // Set post status to spam
2455 $topic['post_status'] = $bbp->spam_status_id;
2456
2457 // No revisions
2458 remove_action( 'pre_post_update', 'wp_save_post_revision' );
2459
2460 // Update the topic
2461 $topic_id = wp_insert_post( $topic );
2462
2463 // Execute post spam code
2464 do_action( 'bbp_spammed_topic', $topic_id );
2465
2466 // Return topic_id
2467 return $topic_id;
2468 }
2469
2470 /**
2471 * Unspams a topic
2472 *
2473 * @since bbPress (r2740)
2474 *
2475 * @param int $topic_id Topic id
2476 * @uses wp_get_single_post() To get the topic
2477 * @uses do_action() Calls 'bbp_unspam_topic' with the topic id
2478 * @uses get_post_meta() To get the previous status
2479 * @uses delete_post_meta() To delete the previous status meta
2480 * @uses wp_insert_post() To update the topic with the new status
2481 * @uses do_action() Calls 'bbp_unspammed_topic' with the topic id
2482 * @return mixed False or {@link WP_Error} on failure, topic id on success
2483 */
2484 function bbp_unspam_topic( $topic_id = 0 ) {
2485 global $bbp;
2486
2487 // Get the topic
2488 if ( !$topic = wp_get_single_post( $topic_id, ARRAY_A ) )
2489 return $topic;
2490
2491 // Bail if already not spam
2492 if ( $topic['post_status'] != $bbp->spam_status_id )
2493 return false;
2494
2495 // Execute pre unspam code
2496 do_action( 'bbp_unspam_topic', $topic_id );
2497
2498 // Get pre spam status
2499 $topic_status = get_post_meta( $topic_id, '_bbp_spam_meta_status', true );
2500
2501 // Set post status to pre spam
2502 $topic['post_status'] = $topic_status;
2503
2504 // Delete pre spam meta
2505 delete_post_meta( $topic_id, '_bbp_spam_meta_status' );
2506
2507 // No revisions
2508 remove_action( 'pre_post_update', 'wp_save_post_revision' );
2509
2510 // Get pre-spam topic tags
2511 $terms = get_post_meta( $topic_id, '_bbp_spam_topic_tags', true );
2512
2513 // Topic had tags before it was spammed
2514 if ( !empty( $terms ) ) {
2515
2516 // Set the tax_input of the topic
2517 $topic['tax_input'] = array( bbp_get_topic_tag_tax_id() => $terms );
2518
2519 // Delete pre-spam topic tag meta
2520 delete_post_meta( $topic_id, '_bbp_spam_topic_tags' );
2521 }
2522
2523 // Update the topic
2524 $topic_id = wp_insert_post( $topic );
2525
2526 // Execute post unspam code
2527 do_action( 'bbp_unspammed_topic', $topic_id );
2528
2529 // Return topic_id
2530 return $topic_id;
2531 }
2532
2533 /**
2534 * Sticks a topic to a forum or front
2535 *
2536 * @since bbPress (r2754)
2537 *
2538 * @param int $topic_id Optional. Topic id
2539 * @param int $super Should we make the topic a super sticky?
2540 * @uses bbp_get_topic_id() To get the topic id
2541 * @uses bbp_unstick_topic() To unstick the topic
2542 * @uses bbp_get_topic_forum_id() To get the topic forum id
2543 * @uses bbp_get_stickies() To get the stickies
2544 * @uses do_action() 'bbp_stick_topic' with topic id and bool super
2545 * @uses update_option() To update the super stickies option
2546 * @uses update_post_meta() To update the forum stickies meta
2547 * @uses do_action() Calls 'bbp_sticked_topic' with the topic id, bool super
2548 * and success
2549 * @return bool True on success, false on failure
2550 */
2551 function bbp_stick_topic( $topic_id = 0, $super = false ) {
2552 $topic_id = bbp_get_topic_id( $topic_id );
2553
2554 // We may have a super sticky to which we want to convert into a normal sticky and vice versa
2555 // So, unstick the topic first to avoid any possible error
2556 bbp_unstick_topic( $topic_id );
2557
2558 $forum_id = empty( $super ) ? bbp_get_topic_forum_id( $topic_id ) : 0;
2559 $stickies = bbp_get_stickies( $forum_id );
2560
2561 do_action( 'bbp_stick_topic', $topic_id, $super );
2562
2563 if ( !is_array( $stickies ) )
2564 $stickies = array( $topic_id );
2565 else
2566 $stickies[] = $topic_id;
2567
2568 $stickies = array_unique( array_filter( $stickies ) );
2569
2570 $success = !empty( $super ) ? update_option( '_bbp_super_sticky_topics', $stickies ) : update_post_meta( $forum_id, '_bbp_sticky_topics', $stickies );
2571
2572 do_action( 'bbp_sticked_topic', $topic_id, $super, $success );
2573
2574 return $success;
2575 }
2576
2577 /**
2578 * Unsticks a topic both from front and it's forum
2579 *
2580 * @since bbPress (r2754)
2581 *
2582 * @param int $topic_id Optional. Topic id
2583 * @uses bbp_get_topic_id() To get the topic id
2584 * @uses bbp_is_topic_super_sticky() To check if the topic is a super sticky
2585 * @uses bbp_get_topic_forum_id() To get the topic forum id
2586 * @uses bbp_get_stickies() To get the forum stickies
2587 * @uses do_action() Calls 'bbp_unstick_topic' with the topic id
2588 * @uses delete_option() To delete the super stickies option
2589 * @uses update_option() To update the super stickies option
2590 * @uses delete_post_meta() To delete the forum stickies meta
2591 * @uses update_post_meta() To update the forum stickies meta
2592 * @uses do_action() Calls 'bbp_unsticked_topic' with the topic id and success
2593 * @return bool Always true.
2594 */
2595 function bbp_unstick_topic( $topic_id = 0 ) {
2596 $topic_id = bbp_get_topic_id( $topic_id );
2597 $super = bbp_is_topic_super_sticky( $topic_id );
2598 $forum_id = empty( $super ) ? bbp_get_topic_forum_id( $topic_id ) : 0;
2599 $stickies = bbp_get_stickies( $forum_id );
2600 $offset = array_search( $topic_id, $stickies );
2601
2602 do_action( 'bbp_unstick_topic', $topic_id );
2603
2604 if ( empty( $stickies ) ) {
2605 $success = true;
2606 } elseif ( !in_array( $topic_id, $stickies ) ) {
2607 $success = true;
2608 } elseif ( false === $offset ) {
2609 $success = true;
2610 } else {
2611 array_splice( $stickies, $offset, 1 );
2612 if ( empty( $stickies ) )
2613 $success = !empty( $super ) ? delete_option( '_bbp_super_sticky_topics' ) : delete_post_meta( $forum_id, '_bbp_sticky_topics' );
2614 else
2615 $success = !empty( $super ) ? update_option( '_bbp_super_sticky_topics', $stickies ) : update_post_meta( $forum_id, '_bbp_sticky_topics', $stickies );
2616 }
2617
2618 do_action( 'bbp_unsticked_topic', $topic_id, $success );
2619
2620 return true;
2621 }
2622
2623 /** Before Delete/Trash/Untrash ***********************************************/
2624
2625 /**
2626 * Called before deleting a topic
2627 *
2628 * @uses bbp_get_topic_id() To get the topic id
2629 * @uses bbp_is_topic() To check if the passed id is a topic
2630 * @uses do_action() Calls 'bbp_delete_topic' with the topic id
2631 * @uses bbp_has_replies() To check if the topic has replies
2632 * @uses bbp_replies() To loop through the replies
2633 * @uses bbp_the_reply() To set a reply as the current reply in the loop
2634 * @uses bbp_get_reply_id() To get the reply id
2635 * @uses wp_delete_post() To delete the reply
2636 */
2637 function bbp_delete_topic( $topic_id = 0 ) {
2638 $topic_id = bbp_get_topic_id( $topic_id );
2639
2640 if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
2641 return false;
2642
2643 do_action( 'bbp_delete_topic', $topic_id );
2644
2645 // Topic is being permanently deleted, so its replies gotta go too
2646 if ( bbp_has_replies( array( 'post_parent' => $topic_id, 'post_status' => 'publish', 'posts_per_page' => -1 ) ) ) {
2647 while ( bbp_replies() ) {
2648 bbp_the_reply();
2649 wp_delete_post( bbp_get_reply_id(), true );
2650 }
2651 }
2652 }
2653
2654 /**
2655 * Called before trashing a topic
2656 *
2657 * @uses bbp_get_topic_id() To get the topic id
2658 * @uses bbp_is_topic() To check if the passed id is a topic
2659 * @uses do_action() Calls 'bbp_trash_topic' with the topic id
2660 * @uses bbp_has_replies() To check if the topic has replies
2661 * @uses bbp_replies() To loop through the replies
2662 * @uses bbp_the_reply() To set a reply as the current reply in the loop
2663 * @uses bbp_get_reply_id() To get the reply id
2664 * @uses wp_trash_post() To trash the reply
2665 * @uses update_post_meta() To save a list of just trashed replies for future use
2666 */
2667 function bbp_trash_topic( $topic_id = 0 ) {
2668 $topic_id = bbp_get_topic_id( $topic_id );
2669
2670 if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
2671 return false;
2672
2673 do_action( 'bbp_trash_topic', $topic_id );
2674
2675 // Topic is being trashed, so its replies are trashed too
2676 if ( bbp_has_replies( array( 'post_parent' => $topic_id, 'post_status' => 'publish', 'posts_per_page' => -1 ) ) ) {
2677 global $bbp;
2678
2679 // Prevent debug notices
2680 $pre_trashed_replies = array();
2681
2682 // Loop through replies, trash them, and add them to array
2683 while ( bbp_replies() ) {
2684 bbp_the_reply();
2685 wp_trash_post( $bbp->reply_query->post->ID );
2686 $pre_trashed_replies[] = $bbp->reply_query->post->ID;
2687 }
2688
2689 // Set a post_meta entry of the replies that were trashed by this action.
2690 // This is so we can possibly untrash them, without untrashing replies
2691 // that were purposefully trashed before.
2692 update_post_meta( $topic_id, '_bbp_pre_trashed_replies', $pre_trashed_replies );
2693 }
2694 }
2695
2696 /**
2697 * Called before untrashing a topic
2698 *
2699 * @uses bbp_get_topic_id() To get the topic id
2700 * @uses bbp_is_topic() To check if the passed id is a topic
2701 * @uses do_action() Calls 'bbp_untrash_topic' with the topic id
2702 * @uses get_post_meta() To get the list of replies which were trashed with the
2703 * topic
2704 * @uses wp_untrash_post() To untrash the reply
2705 */
2706 function bbp_untrash_topic( $topic_id = 0 ) {
2707 $topic_id = bbp_get_topic_id( $topic_id );
2708
2709 if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
2710 return false;
2711
2712 do_action( 'bbp_untrash_topic', $topic_id );
2713
2714 // Get the replies that were not previously trashed
2715 $pre_trashed_replies = get_post_meta( $topic_id, '_bbp_pre_trashed_replies', true );
2716
2717 // There are replies to untrash
2718 if ( !empty( $pre_trashed_replies ) ) {
2719
2720 // Maybe reverse the trashed replies array
2721 if ( is_array( $pre_trashed_replies ) )
2722 $pre_trashed_replies = array_reverse( $pre_trashed_replies );
2723
2724 // Loop through replies
2725 foreach ( (array) $pre_trashed_replies as $reply ) {
2726 wp_untrash_post( $reply );
2727 }
2728 }
2729 }
2730
2731 /** After Delete/Trash/Untrash ************************************************/
2732
2733 /**
2734 * Called after deleting a topic
2735 *
2736 * @uses bbp_get_topic_id() To get the topic id
2737 * @uses bbp_is_topic() To check if the passed id is a topic
2738 * @uses do_action() Calls 'bbp_deleted_topic' with the topic id
2739 */
2740 function bbp_deleted_topic( $topic_id = 0 ) {
2741 $topic_id = bbp_get_topic_id( $topic_id );
2742
2743 if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
2744 return false;
2745
2746 do_action( 'bbp_deleted_topic', $topic_id );
2747 }
2748
2749 /**
2750 * Called after trashing a topic
2751 *
2752 * @uses bbp_get_topic_id() To get the topic id
2753 * @uses bbp_is_topic() To check if the passed id is a topic
2754 * @uses do_action() Calls 'bbp_trashed_topic' with the topic id
2755 */
2756 function bbp_trashed_topic( $topic_id = 0 ) {
2757 $topic_id = bbp_get_topic_id( $topic_id );
2758
2759 if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
2760 return false;
2761
2762 do_action( 'bbp_trashed_topic', $topic_id );
2763 }
2764
2765 /**
2766 * Called after untrashing a topic
2767 *
2768 * @uses bbp_get_topic_id() To get the topic id
2769 * @uses bbp_is_topic() To check if the passed id is a topic
2770 * @uses do_action() Calls 'bbp_untrashed_topic' with the topic id
2771 */
2772 function bbp_untrashed_topic( $topic_id = 0 ) {
2773 $topic_id = bbp_get_topic_id( $topic_id );
2774
2775 if ( empty( $topic_id ) || !bbp_is_topic( $topic_id ) )
2776 return false;
2777
2778 do_action( 'bbp_untrashed_topic', $topic_id );
2779 }
2780
2781 /** Feeds *********************************************************************/
2782
2783 /**
2784 * Output an RSS2 feed of topics, based on the query passed.
2785 *
2786 * @since bbPress (r3171)
2787 *
2788 * @uses bbp_version()
2789 * @uses bbp_is_single_topic()
2790 * @uses bbp_user_can_view_forum()
2791 * @uses bbp_get_topic_forum_id()
2792 * @uses bbp_show_load_topic()
2793 * @uses bbp_topic_permalink()
2794 * @uses bbp_topic_title()
2795 * @uses bbp_get_topic_reply_count()
2796 * @uses bbp_topic_content()
2797 * @uses bbp_has_topics()
2798 * @uses bbp_topics()
2799 * @uses bbp_the_topic()
2800 * @uses get_wp_title_rss()
2801 * @uses get_option()
2802 * @uses bloginfo_rss
2803 * @uses self_link()
2804 * @uses the_author()
2805 * @uses get_post_time()
2806 * @uses rss_enclosure()
2807 * @uses do_action()
2808 * @uses apply_filters()
2809 *
2810 * @param array $topics_query
2811 */
2812 function bbp_display_topics_feed_rss2( $topics_query = array() ) {
2813
2814 // User cannot access this forum
2815 if ( bbp_is_single_forum() && !bbp_user_can_view_forum( array( 'forum_id' => bbp_get_forum_id() ) ) )
2816 return;
2817
2818 // Display the feed
2819 header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
2820 header( 'Status: 200 OK' );
2821 echo '<?xml version="1.0" encoding="' . get_option( 'blog_charset' ) . '"?' . '>'; ?>
2822
2823 <rss version="2.0"
2824 xmlns:content="http://purl.org/rss/1.0/modules/content/"
2825 xmlns:wfw="http://wellformedweb.org/CommentAPI/"
2826 xmlns:dc="http://purl.org/dc/elements/1.1/"
2827 xmlns:atom="http://www.w3.org/2005/Atom"
2828
2829 <?php do_action( 'bbp_feed' ); ?>
2830 >
2831
2832 <channel>
2833
2834 <title><?php bloginfo_rss( 'name' ); ?> &#187; <?php _e( 'All Topics', 'bbpress' ); ?></title>
2835 <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
2836 <link><?php self_link(); ?></link>
2837 <description><?php //?></description>
2838 <pubDate><?php echo mysql2date( 'D, d M Y H:i:s O', '', false ); ?></pubDate>
2839 <generator>http://bbpress.org/?v=<?php bbp_version(); ?></generator>
2840 <language><?php echo get_option( 'rss_language' ); ?></language>
2841
2842 <?php do_action( 'bbp_feed_head' ); ?>
2843
2844 <?php if ( bbp_has_topics( $topics_query ) ) : ?>
2845
2846 <?php while ( bbp_topics() ) : bbp_the_topic(); ?>
2847
2848 <item>
2849 <guid><?php bbp_topic_permalink(); ?></guid>
2850 <title><![CDATA[<?php bbp_topic_title(); ?>]]></title>
2851 <link><?php bbp_topic_permalink(); ?></link>
2852 <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_meta( bbp_get_topic_id(), '_bbp_last_active_time', true ) ); ?></pubDate>
2853 <dc:creator><?php the_author() ?></dc:creator>
2854
2855 <?php if ( !post_password_required() ) : ?>
2856
2857 <description>
2858 <![CDATA[
2859 <p><?php printf( __( 'Replies: %s', 'bbpress' ), bbp_get_topic_reply_count() ); ?></p>
2860 <?php bbp_topic_content(); ?>
2861 ]]>
2862 </description>
2863
2864 <?php rss_enclosure(); ?>
2865
2866 <?php endif; ?>
2867
2868 <?php do_action( 'bbp_feed_item' ); ?>
2869
2870 </item>
2871
2872 <?php endwhile; ?>
2873 <?php endif; ?>
2874
2875 <?php do_action( 'bbp_feed_footer' ); ?>
2876
2877 </channel>
2878 </rss>
2879
2880 <?php
2881 exit();
2882 }
2883
2884 ?>
2885