PluginProbe
bbPress / 2.1-beta-1
bbPress v2.1-beta-1
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.1-beta-1, at bbp-includes/bbp-topic-functions.php

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