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

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

1,600 lines 53.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * bbPress Reply 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 reply to function properly.
18 *
19 * @since bbPress (r3349)
20 *
21 * @uses bbp_parse_args()
22 * @uses bbp_get_reply_post_type()
23 * @uses wp_insert_post()
24 * @uses update_post_meta()
25 *
26 * @param array $reply_data Forum post data
27 * @param arrap $reply_meta Forum meta data
28 */
29 function bbp_insert_reply( $reply_data = array(), $reply_meta = array() ) {
30
31 // Forum
32 $default_reply = array(
33 'post_parent' => 0, // topic ID
34 'post_status' => bbp_get_public_status_id(),
35 'post_type' => bbp_get_reply_post_type(),
36 'post_author' => bbp_get_current_user_id(),
37 'post_password' => '',
38 'post_content' => '',
39 'post_title' => '',
40 'menu_order' => 0,
41 'comment_status' => 'closed'
42 );
43 $reply_data = bbp_parse_args( $reply_data, $default_reply, 'insert_reply' );
44
45 // Insert reply
46 $reply_id = wp_insert_post( $reply_data );
47
48 // Bail if no reply was added
49 if ( empty( $reply_id ) )
50 return false;
51
52 // Forum meta
53 $default_meta = array(
54 'author_ip' => bbp_current_author_ip(),
55 'forum_id' => 0,
56 'topic_id' => 0,
57 );
58 $reply_meta = bbp_parse_args( $reply_meta, $default_meta, 'insert_reply_meta' );
59
60 // Insert reply meta
61 foreach ( $reply_meta as $meta_key => $meta_value )
62 update_post_meta( $reply_id, '_bbp_' . $meta_key, $meta_value );
63
64 // Update the topic
65 $topic_id = bbp_get_reply_topic_id( $reply_id );
66 if ( !empty( $topic_id ) )
67 bbp_update_topic( $topic_id );
68
69 // Return new reply ID
70 return $reply_id;
71 }
72
73 /** Post Form Handlers ********************************************************/
74
75 /**
76 * Handles the front end reply submission
77 *
78 * @since bbPress (r2574)
79 *
80 * @uses bbp_add_error() To add an error message
81 * @uses check_admin_referer() To verify the nonce and check the referer
82 * @uses bbp_is_anonymous() To check if an anonymous post is being made
83 * @uses current_user_can() To check if the current user can publish replies
84 * @uses bbp_get_current_user_id() To get the current user id
85 * @uses bbp_filter_anonymous_post_data() To filter anonymous data
86 * @uses bbp_set_current_anonymous_user_data() To set the anonymous user
87 * cookies
88 * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
89 * @uses remove_filter() To remove 'wp_filter_kses' filters if needed
90 * @uses esc_attr() For sanitization
91 * @uses bbp_check_for_flood() To check for flooding
92 * @uses bbp_check_for_duplicate() To check for duplicates
93 * @uses apply_filters() Calls 'bbp_new_reply_pre_title' with the title
94 * @uses apply_filters() Calls 'bbp_new_reply_pre_content' with the content
95 * @uses bbp_get_reply_post_type() To get the reply post type
96 * @uses wp_set_post_terms() To set the topic tags
97 * @uses wp_insert_post() To insert the reply
98 * @uses do_action() Calls 'bbp_new_reply' with the reply id, topic id, forum
99 * id, anonymous data and reply author
100 * @uses bbp_get_reply_url() To get the paginated url to the reply
101 * @uses wp_safe_redirect() To redirect to the reply url
102 * @uses bbPress::errors::get_error_message() To get the {@link WP_Error} error
103 * message
104 */
105 function bbp_new_reply_handler() {
106
107 // Bail if not a POST action
108 if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
109 return;
110
111 // Bail if action is not bbp-new-reply
112 if ( empty( $_POST['action'] ) || ( 'bbp-new-reply' !== $_POST['action'] ) )
113 return;
114
115 // Nonce check
116 check_admin_referer( 'bbp-new-reply' );
117
118 // Define local variable(s)
119 $topic_id = $forum_id = $reply_author = $anonymous_data = 0;
120 $reply_title = $reply_content = $terms = '';
121
122 /** Reply Author **********************************************************/
123
124 // User is anonymous
125 if ( bbp_is_anonymous() ) {
126
127 // Filter anonymous data
128 $anonymous_data = bbp_filter_anonymous_post_data();
129
130 // Anonymous data checks out, so set cookies, etc...
131 if ( !empty( $anonymous_data ) && is_array( $anonymous_data ) ) {
132 bbp_set_current_anonymous_user_data( $anonymous_data );
133 }
134
135 // User is logged in
136 } else {
137
138 // User cannot create replies
139 if ( !current_user_can( 'publish_replies' ) ) {
140 bbp_add_error( 'bbp_reply_permissions', __( '<strong>ERROR</strong>: You do not have permission to reply.', 'bbpress' ) );
141 }
142
143 // Reply author is current user
144 $reply_author = bbp_get_current_user_id();
145
146 }
147
148 /** Topic ID **************************************************************/
149
150 // Handle Topic ID to append reply to
151 if ( isset( $_POST['bbp_topic_id'] ) ) {
152 $topic_id = (int) $_POST['bbp_topic_id'];
153 } else {
154 bbp_add_error( 'bbp_reply_topic_id', __( '<strong>ERROR</strong>: Topic ID is missing.', 'bbpress' ) );
155 }
156
157 /** Forum ID **************************************************************/
158
159 // Handle Forum ID to adjust counts of
160 if ( isset( $_POST['bbp_forum_id'] ) ) {
161 $forum_id = (int) $_POST['bbp_forum_id'];
162 } elseif ( !empty( $topic_id ) ) {
163 $forum_id = bbp_get_topic_forum_id( $topic_id );
164 } else {
165 bbp_add_error( 'bbp_reply_forum_id', __( '<strong>ERROR</strong>: Forum ID is missing.', 'bbpress' ) );
166 }
167
168 /** Unfiltered HTML *******************************************************/
169
170 // Remove wp_filter_kses filters from title and content for capable users and if the nonce is verified
171 if ( current_user_can( 'unfiltered_html' ) && !empty( $_POST['_bbp_unfiltered_html_reply'] ) && wp_create_nonce( 'bbp-unfiltered-html-reply_' . $topic_id ) == $_POST['_bbp_unfiltered_html_reply'] ) {
172 remove_filter( 'bbp_new_reply_pre_title', 'wp_filter_kses' );
173 remove_filter( 'bbp_new_reply_pre_content', 'wp_filter_kses' );
174 }
175
176 /** Reply Title ***********************************************************/
177
178 if ( !empty( $_POST['bbp_reply_title'] ) )
179 $reply_title = esc_attr( strip_tags( $_POST['bbp_reply_title'] ) );
180
181 // Filter and sanitize
182 $reply_title = apply_filters( 'bbp_new_reply_pre_title', $reply_title );
183
184 // No reply title
185 if ( empty( $reply_title ) )
186 bbp_add_error( 'bbp_reply_title', __( '<strong>ERROR</strong>: Your reply needs a title.', 'bbpress' ) );
187
188 /** Reply Content *********************************************************/
189
190 if ( !empty( $_POST['bbp_reply_content'] ) )
191 $reply_content = $_POST['bbp_reply_content'];
192
193 // Filter and sanitize
194 $reply_content = apply_filters( 'bbp_new_reply_pre_content', $reply_content );
195
196 // No reply content
197 if ( empty( $reply_content ) )
198 bbp_add_error( 'bbp_reply_content', __( '<strong>ERROR</strong>: Your reply cannot be empty.', 'bbpress' ) );
199
200 /** Reply Flooding ********************************************************/
201
202 if ( !bbp_check_for_flood( $anonymous_data, $reply_author ) )
203 bbp_add_error( 'bbp_reply_flood', __( '<strong>ERROR</strong>: Slow down; you move too fast.', 'bbpress' ) );
204
205 /** Reply Duplicate *******************************************************/
206
207 if ( !bbp_check_for_duplicate( array( 'post_type' => bbp_get_reply_post_type(), 'post_author' => $reply_author, 'post_content' => $reply_content, 'post_parent' => $topic_id, 'anonymous_data' => $anonymous_data ) ) )
208 bbp_add_error( 'bbp_reply_duplicate', __( '<strong>ERROR</strong>: Duplicate reply detected; it looks as though you&#8217;ve already said that!', 'bbpress' ) );
209
210 /** Reply Blacklist *******************************************************/
211
212 if ( !bbp_check_for_blacklist( $anonymous_data, $reply_author, $reply_title, $reply_content ) )
213 bbp_add_error( 'bbp_reply_blacklist', __( '<strong>ERROR</strong>: Your reply cannot be created at this time.', 'bbpress' ) );
214
215 /** Reply Moderation ******************************************************/
216
217 $post_status = bbp_get_public_status_id();
218 if ( !bbp_check_for_moderation( $anonymous_data, $reply_author, $reply_title, $reply_content ) )
219 $post_status = bbp_get_pending_status_id();
220
221 /** Topic Tags ************************************************************/
222
223 if ( !empty( $_POST['bbp_topic_tags'] ) )
224 $terms = esc_attr( strip_tags( $_POST['bbp_topic_tags'] ) );
225
226 /** Additional Actions (Before Save) **************************************/
227
228 do_action( 'bbp_new_reply_pre_extras' );
229
230 /** No Errors *************************************************************/
231
232 // Handle insertion into posts table
233 if ( !bbp_has_errors() ) {
234
235 /** Create new reply **************************************************/
236
237 // Add the content of the form to $reply_data as an array
238 $reply_data = array(
239 'post_author' => $reply_author,
240 'post_title' => $reply_title,
241 'post_content' => $reply_content,
242 'post_parent' => $topic_id,
243 'post_status' => $post_status,
244 'post_type' => bbp_get_reply_post_type(),
245 'comment_status' => 'closed',
246 'menu_order' => (int) ( bbp_get_topic_reply_count( $topic_id ) + 1 )
247 );
248
249 // Just in time manipulation of reply data before being created
250 $reply_data = apply_filters( 'bbp_new_reply_pre_insert', $reply_data );
251
252 // Insert reply
253 $reply_id = wp_insert_post( $reply_data );
254
255 /** No Errors *********************************************************/
256
257 // Check for missing reply_id or error
258 if ( !empty( $reply_id ) && !is_wp_error( $reply_id ) ) {
259
260 /** Topic Tags ****************************************************/
261
262 // Just in time manipulation of reply terms before being edited
263 $terms = apply_filters( 'bbp_new_reply_pre_set_terms', $terms, $topic_id, $reply_id );
264
265 // Insert terms
266 $terms = wp_set_post_terms( $topic_id, $terms, bbp_get_topic_tag_tax_id(), false );
267
268 // Term error
269 if ( is_wp_error( $terms ) ) {
270 bbp_add_error( 'bbp_reply_tags', __( '<strong>ERROR</strong>: There was a problem adding the tags to the topic.', 'bbpress' ) );
271 }
272
273 /** Trash Check ***************************************************/
274
275 // If this reply starts as trash, add it to pre_trashed_replies
276 // for the topic, so it is properly restored.
277 if ( bbp_is_topic_trash( $topic_id ) || ( $reply_data['post_status'] == bbp_get_trash_status_id() ) ) {
278
279 // Trash the reply
280 wp_trash_post( $reply_id );
281
282 // Get pre_trashed_replies for topic
283 $pre_trashed_replies = get_post_meta( $topic_id, '_bbp_pre_trashed_replies', true );
284
285 // Add this reply to the end of the existing replies
286 $pre_trashed_replies[] = $reply_id;
287
288 // Update the pre_trashed_reply post meta
289 update_post_meta( $topic_id, '_bbp_pre_trashed_replies', $pre_trashed_replies );
290 }
291
292 /** Spam Check ****************************************************/
293
294 // If reply or topic are spam, officially spam this reply
295 if ( bbp_is_topic_spam( $topic_id ) || ( $reply_data['post_status'] == bbp_get_spam_status_id() ) )
296 add_post_meta( $reply_id, '_bbp_spam_meta_status', bbp_get_public_status_id() );
297
298 /** Update counts, etc... *****************************************/
299
300 do_action( 'bbp_new_reply', $reply_id, $topic_id, $forum_id, $anonymous_data, $reply_author );
301
302 /** Additional Actions (After Save) *******************************/
303
304 do_action( 'bbp_new_reply_post_extras', $reply_id );
305
306 /** Redirect ******************************************************/
307
308 // Redirect to
309 $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
310
311 // Get the reply URL
312 $reply_url = bbp_get_reply_url( $reply_id, $redirect_to );
313
314 // Allow to be filtered
315 $reply_url = apply_filters( 'bbp_new_reply_redirect_to', $reply_url, $redirect_to, $reply_id );
316
317 /** Successful Save ***********************************************/
318
319 // Redirect back to new reply
320 wp_safe_redirect( $reply_url );
321
322 // For good measure
323 exit();
324
325 /** Errors ************************************************************/
326
327 } else {
328 $append_error = ( is_wp_error( $reply_id ) && $reply_id->get_error_message() ) ? $reply_id->get_error_message() . ' ' : '';
329 bbp_add_error( 'bbp_reply_error', __( '<strong>ERROR</strong>: The following problem(s) have been found with your reply:' . $append_error . 'Please try again.', 'bbpress' ) );
330 }
331 }
332 }
333
334 /**
335 * Handles the front end edit reply submission
336 *
337 * @uses bbp_add_error() To add an error message
338 * @uses bbp_get_reply() To get the reply
339 * @uses check_admin_referer() To verify the nonce and check the referer
340 * @uses bbp_is_reply_anonymous() To check if the reply was by an anonymous user
341 * @uses current_user_can() To check if the current user can edit that reply
342 * @uses bbp_filter_anonymous_post_data() To filter anonymous data
343 * @uses is_wp_error() To check if the value retrieved is a {@link WP_Error}
344 * @uses remove_filter() To remove 'wp_filter_kses' filters if needed
345 * @uses esc_attr() For sanitization
346 * @uses apply_filters() Calls 'bbp_edit_reply_pre_title' with the title and
347 * reply id
348 * @uses apply_filters() Calls 'bbp_edit_reply_pre_content' with the content
349 * reply id
350 * @uses wp_set_post_terms() To set the topic tags
351 * @uses bbp_has_errors() To get the {@link WP_Error} errors
352 * @uses wp_save_post_revision() To save a reply revision
353 * @uses bbp_update_topic_revision_log() To update the reply revision log
354 * @uses wp_update_post() To update the reply
355 * @uses bbp_get_reply_topic_id() To get the reply topic id
356 * @uses bbp_get_topic_forum_id() To get the topic forum id
357 * @uses do_action() Calls 'bbp_edit_reply' with the reply id, topic id, forum
358 * id, anonymous data, reply author and bool true (for edit)
359 * @uses bbp_get_reply_url() To get the paginated url to the reply
360 * @uses wp_safe_redirect() To redirect to the reply url
361 * @uses bbPress::errors::get_error_message() To get the {@link WP_Error} error
362 * message
363 */
364 function bbp_edit_reply_handler() {
365
366 // Bail if not a POST action
367 if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
368 return;
369
370 // Bail if action is not bbp-edit-reply
371 if ( empty( $_POST['action'] ) || ( 'bbp-edit-reply' !== $_POST['action'] ) )
372 return;
373
374 // Define local variable(s)
375 $reply = $reply_id = $topic_id = $forum_id = $anonymous_data = 0;
376 $reply_title = $reply_content = $reply_edit_reason = $terms = '';
377
378 /** Reply *****************************************************************/
379
380 // Reply id was not passed
381 if ( empty( $_POST['bbp_reply_id'] ) ) {
382 bbp_add_error( 'bbp_edit_reply_id', __( '<strong>ERROR</strong>: Reply ID not found.', 'bbpress' ) );
383
384 // Reply id was passed
385 } elseif ( is_numeric( $_POST['bbp_reply_id'] ) ) {
386 $reply_id = (int) $_POST['bbp_reply_id'];
387 $reply = bbp_get_reply( $reply_id );
388 }
389
390 // Reply does not exist
391 if ( empty( $reply ) ) {
392 bbp_add_error( 'bbp_edit_reply_not_found', __( '<strong>ERROR</strong>: The reply you want to edit was not found.', 'bbpress' ) );
393
394 // Reply exists
395 } else {
396
397 // Nonce check
398 check_admin_referer( 'bbp-edit-reply_' . $reply_id );
399
400 // Check users ability to create new reply
401 if ( !bbp_is_reply_anonymous( $reply_id ) ) {
402
403 // User cannot edit this reply
404 if ( !current_user_can( 'edit_reply', $reply_id ) ) {
405 bbp_add_error( 'bbp_edit_reply_permissions', __( '<strong>ERROR</strong>: You do not have permission to edit that reply.', 'bbpress' ) );
406 }
407
408 // It is an anonymous post
409 } else {
410
411 // Filter anonymous data
412 $anonymous_data = bbp_filter_anonymous_post_data();
413 }
414 }
415
416 // Remove wp_filter_kses filters from title and content for capable users and if the nonce is verified
417 if ( current_user_can( 'unfiltered_html' ) && !empty( $_POST['_bbp_unfiltered_html_reply'] ) && wp_create_nonce( 'bbp-unfiltered-html-reply_' . $reply_id ) == $_POST['_bbp_unfiltered_html_reply'] ) {
418 remove_filter( 'bbp_edit_reply_pre_title', 'wp_filter_kses' );
419 remove_filter( 'bbp_edit_reply_pre_content', 'wp_filter_kses' );
420 }
421
422 /** Reply Topic ***********************************************************/
423
424 $topic_id = bbp_get_reply_topic_id( $reply_id );
425
426 /** Topic Forum ***********************************************************/
427
428 $forum_id = bbp_get_topic_forum_id( $topic_id );
429
430 // Forum exists
431 if ( !empty( $forum_id ) && ( $forum_id !== bbp_get_reply_forum_id( $reply_id ) ) ) {
432
433 // Forum is a category
434 if ( bbp_is_forum_category( $forum_id ) )
435 bbp_add_error( 'bbp_edit_reply_forum_category', __( '<strong>ERROR</strong>: This forum is a category. No topics or replies can be created in it.', 'bbpress' ) );
436
437 // Forum is closed and user cannot access
438 if ( bbp_is_forum_closed( $forum_id ) && !current_user_can( 'edit_forum', $forum_id ) )
439 bbp_add_error( 'bbp_edit_reply_forum_closed', __( '<strong>ERROR</strong>: This forum has been closed to new topics and replies.', 'bbpress' ) );
440
441 // Forum is private and user cannot access
442 if ( bbp_is_forum_private( $forum_id ) && !current_user_can( 'read_private_forums' ) )
443 bbp_add_error( 'bbp_edit_reply_forum_private', __( '<strong>ERROR</strong>: This forum is private and you do not have the capability to read or create new replies in it.', 'bbpress' ) );
444
445 // Forum is hidden and user cannot access
446 if ( bbp_is_forum_hidden( $forum_id ) && !current_user_can( 'read_hidden_forums' ) )
447 bbp_add_error( 'bbp_edit_reply_forum_hidden', __( '<strong>ERROR</strong>: This forum is hidden and you do not have the capability to read or create new replies in it.', 'bbpress' ) );
448 }
449
450 /** Reply Title ***********************************************************/
451
452 if ( !empty( $_POST['bbp_reply_title'] ) )
453 $reply_title = esc_attr( strip_tags( $_POST['bbp_reply_title'] ) );
454
455 // Filter and sanitize
456 $reply_title = apply_filters( 'bbp_edit_reply_pre_title', $reply_title, $reply_id );
457
458 /** Reply Content *********************************************************/
459
460 if ( !empty( $_POST['bbp_reply_content'] ) )
461 $reply_content = $_POST['bbp_reply_content'];
462
463 // Filter and sanitize
464 $reply_content = apply_filters( 'bbp_edit_reply_pre_content', $reply_content, $reply_id );
465
466 // No reply content
467 if ( empty( $reply_content ) )
468 bbp_add_error( 'bbp_edit_reply_content', __( '<strong>ERROR</strong>: Your reply cannot be empty.', 'bbpress' ) );
469
470 /** Reply Blacklist *******************************************************/
471
472 if ( !bbp_check_for_blacklist( $anonymous_data, bbp_get_reply_author_id( $reply_id ), $reply_title, $reply_content ) )
473 bbp_add_error( 'bbp_reply_blacklist', __( '<strong>ERROR</strong>: Your reply cannot be edited at this time.', 'bbpress' ) );
474
475 /** Reply Moderation ******************************************************/
476
477 $post_status = bbp_get_public_status_id();
478 if ( !bbp_check_for_moderation( $anonymous_data, bbp_get_reply_author_id( $reply_id ), $reply_title, $reply_content ) )
479 $post_status = bbp_get_pending_status_id();
480
481 /** Topic Tags ************************************************************/
482
483 if ( !empty( $_POST['bbp_topic_tags'] ) )
484 $terms = esc_attr( strip_tags( $_POST['bbp_topic_tags'] ) );
485
486 /** Additional Actions (Before Save) **************************************/
487
488 do_action( 'bbp_edit_reply_pre_extras', $reply_id );
489
490 /** No Errors *************************************************************/
491
492 // Handle insertion into posts table
493 if ( !bbp_has_errors() ) {
494
495 // Add the content of the form to $reply_data as an array
496 $reply_data = array(
497 'ID' => $reply_id,
498 'post_title' => $reply_title,
499 'post_content' => $reply_content,
500 'post_status' => $post_status
501 );
502
503 // Just in time manipulation of reply data before being edited
504 $reply_data = apply_filters( 'bbp_edit_reply_pre_insert', $reply_data );
505
506 // Insert reply
507 $reply_id = wp_update_post( $reply_data );
508
509 /** Topic Tags ****************************************************/
510
511 // Just in time manipulation of reply terms before being edited
512 $terms = apply_filters( 'bbp_edit_reply_pre_set_terms', $terms, $topic_id, $reply_id );
513
514 // Insert terms
515 $terms = wp_set_post_terms( $topic_id, $terms, bbp_get_topic_tag_tax_id(), false );
516
517 // Term error
518 if ( is_wp_error( $terms ) ) {
519 bbp_add_error( 'bbp_reply_tags', __( '<strong>ERROR</strong>: There was a problem adding the tags to the topic.', 'bbpress' ) );
520 }
521
522 /** Revisions *********************************************************/
523
524 // Revision Reason
525 if ( !empty( $_POST['bbp_reply_edit_reason'] ) )
526 $reply_edit_reason = esc_attr( strip_tags( $_POST['bbp_reply_edit_reason'] ) );
527
528 // Update revision log
529 if ( !empty( $_POST['bbp_log_reply_edit'] ) && ( 1 == $_POST['bbp_log_reply_edit'] ) ) {
530 $revision_id = wp_save_post_revision( $reply_id );
531 if ( !empty( $revision_id ) ) {
532 bbp_update_reply_revision_log( array(
533 'reply_id' => $reply_id,
534 'revision_id' => $revision_id,
535 'author_id' => bbp_get_current_user_id(),
536 'reason' => $reply_edit_reason
537 ) );
538 }
539 }
540
541 /** No Errors *********************************************************/
542
543 if ( !empty( $reply_id ) && !is_wp_error( $reply_id ) ) {
544
545 // Update counts, etc...
546 do_action( 'bbp_edit_reply', $reply_id, $topic_id, $forum_id, $anonymous_data, $reply->post_author , true /* Is edit */ );
547
548 /** Additional Actions (After Save) *******************************/
549
550 do_action( 'bbp_edit_reply_post_extras', $reply_id );
551
552 /** Redirect ******************************************************/
553
554 // Redirect to
555 $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
556
557 // Get the reply URL
558 $reply_url = bbp_get_reply_url( $reply_id, $redirect_to );
559
560 // Allow to be filtered
561 $reply_url = apply_filters( 'bbp_edit_reply_redirect_to', $reply_url, $redirect_to );
562
563 /** Successful Edit ***********************************************/
564
565 // Redirect back to new reply
566 wp_safe_redirect( $reply_url );
567
568 // For good measure
569 exit();
570
571 /** Errors ************************************************************/
572
573 } else {
574 $append_error = ( is_wp_error( $reply_id ) && $reply_id->get_error_message() ) ? $reply_id->get_error_message() . ' ' : '';
575 bbp_add_error( 'bbp_reply_error', __( '<strong>ERROR</strong>: The following problem(s) have been found with your reply:' . $append_error . 'Please try again.', 'bbpress' ) );
576 }
577 }
578 }
579
580 /**
581 * Handle all the extra meta stuff from posting a new reply or editing a reply
582 *
583 * @param int $reply_id Optional. Reply id
584 * @param int $topic_id Optional. Topic id
585 * @param int $forum_id Optional. Forum id
586 * @param bool|array $anonymous_data Optional. If it is an array, it is
587 * extracted and anonymous user info is saved
588 * @param int $author_id Author id
589 * @param bool $is_edit Optional. Is the post being edited? Defaults to false.
590 * @uses bbp_get_reply_id() To get the reply id
591 * @uses bbp_get_topic_id() To get the topic id
592 * @uses bbp_get_forum_id() To get the forum id
593 * @uses bbp_get_current_user_id() To get the current user id
594 * @uses bbp_get_reply_topic_id() To get the reply topic id
595 * @uses bbp_get_topic_forum_id() To get the topic forum id
596 * @uses update_post_meta() To update the reply metas
597 * @uses set_transient() To update the flood check transient for the ip
598 * @uses bbp_update_user_last_posted() To update the users last posted time
599 * @uses bbp_is_subscriptions_active() To check if the subscriptions feature is
600 * activated or not
601 * @uses bbp_is_user_subscribed() To check if the user is subscribed
602 * @uses bbp_remove_user_subscription() To remove the user's subscription
603 * @uses bbp_add_user_subscription() To add the user's subscription
604 * @uses bbp_update_reply_forum_id() To update the reply forum id
605 * @uses bbp_update_reply_topic_id() To update the reply topic id
606 * @uses bbp_update_reply_walker() To update the reply's ancestors' counts
607 */
608 function bbp_update_reply( $reply_id = 0, $topic_id = 0, $forum_id = 0, $anonymous_data = false, $author_id = 0, $is_edit = false ) {
609
610 // Validate the ID's passed from 'bbp_new_reply' action
611 $reply_id = bbp_get_reply_id( $reply_id );
612 $topic_id = bbp_get_topic_id( $topic_id );
613 $forum_id = bbp_get_forum_id( $forum_id );
614
615 // Bail if there is no reply
616 if ( empty( $reply_id ) )
617 return;
618
619 // Check author_id
620 if ( empty( $author_id ) )
621 $author_id = bbp_get_current_user_id();
622
623 // Check topic_id
624 if ( empty( $topic_id ) )
625 $topic_id = bbp_get_reply_topic_id( $reply_id );
626
627 // Check forum_id
628 if ( !empty( $topic_id ) && empty( $forum_id ) )
629 $forum_id = bbp_get_topic_forum_id( $topic_id );
630
631 // If anonymous post, store name, email, website and ip in post_meta.
632 // It expects anonymous_data to be sanitized.
633 // Check bbp_filter_anonymous_post_data() for sanitization.
634 if ( !empty( $anonymous_data ) && is_array( $anonymous_data ) ) {
635
636 // Always set at least these three values to empty
637 $defaults = array(
638 'bbp_anonymous_name' => '',
639 'bbp_anonymous_email' => '',
640 'bbp_anonymous_website' => '',
641 );
642 $r = bbp_parse_args( $anonymous_data, $defaults, 'update_reply' );
643
644 // Update all anonymous metas
645 foreach( $r as $anon_key => $anon_value ) {
646 update_post_meta( $reply_id, '_' . $anon_key, (string) $anon_value, false );
647 }
648
649 // Set transient for throttle check (only on new, not edit)
650 if ( empty( $is_edit ) ) {
651 set_transient( '_bbp_' . bbp_current_author_ip() . '_last_posted', time() );
652 }
653
654 } else {
655 if ( empty( $is_edit ) && !current_user_can( 'throttle' ) ) {
656 bbp_update_user_last_posted( $author_id );
657 }
658 }
659
660 // Handle Subscription Checkbox
661 if ( bbp_is_subscriptions_active() && !empty( $author_id ) && !empty( $topic_id ) ) {
662 $subscribed = bbp_is_user_subscribed( $author_id, $topic_id );
663 $subscheck = ( !empty( $_POST['bbp_topic_subscription'] ) && ( 'bbp_subscribe' == $_POST['bbp_topic_subscription'] ) ) ? true : false;
664
665 // Subscribed and unsubscribing
666 if ( true == $subscribed && false == $subscheck ) {
667 bbp_remove_user_subscription( $author_id, $topic_id );
668
669 // Subscribing
670 } elseif ( false == $subscribed && true == $subscheck ) {
671 bbp_add_user_subscription( $author_id, $topic_id );
672 }
673 }
674
675 // Reply meta relating to reply position in tree
676 bbp_update_reply_forum_id( $reply_id, $forum_id );
677 bbp_update_reply_topic_id( $reply_id, $topic_id );
678
679 // Update associated topic values if this is a new reply
680 if ( empty( $is_edit ) ) {
681
682 // Update poster IP if not editing
683 update_post_meta( $reply_id, '_bbp_author_ip', bbp_current_author_ip(), false );
684
685 // Last active time
686 $last_active_time = current_time( 'mysql' );
687
688 // Walk up ancestors and do the dirty work
689 bbp_update_reply_walker( $reply_id, $last_active_time, $forum_id, $topic_id, false );
690 }
691 }
692
693 /**
694 * Walk up the ancestor tree from the current reply, and update all the counts
695 *
696 * @since bbPress (r2884)
697 *
698 * @param int $reply_id Optional. Reply id
699 * @param string $last_active_time Optional. Last active time
700 * @param int $forum_id Optional. Forum id
701 * @param int $topic_id Optional. Topic id
702 * @param bool $refresh If set to true, unsets all the previous parameters.
703 * Defaults to true
704 * @uses bbp_get_reply_id() To get the reply id
705 * @uses bbp_get_reply_topic_id() To get the reply topic id
706 * @uses bbp_get_reply_forum_id() To get the reply forum id
707 * @uses get_post_ancestors() To get the ancestors of the reply
708 * @uses bbp_is_reply() To check if the ancestor is a reply
709 * @uses bbp_is_topic() To check if the ancestor is a topic
710 * @uses bbp_update_topic_last_reply_id() To update the topic last reply id
711 * @uses bbp_update_topic_last_active_id() To update the topic last active id
712 * @uses bbp_get_topic_last_active_id() To get the topic last active id
713 * @uses get_post_field() To get the post date of the last active id
714 * @uses bbp_update_topic_last_active_time() To update the last active topic meta
715 * @uses bbp_update_topic_voice_count() To update the topic voice count
716 * @uses bbp_update_topic_reply_count() To update the topic reply count
717 * @uses bbp_update_topic_reply_count_hidden() To update the topic hidden reply
718 * count
719 * @uses bbp_is_forum() To check if the ancestor is a forum
720 * @uses bbp_update_forum_last_topic_id() To update the last topic id forum meta
721 * @uses bbp_update_forum_last_reply_id() To update the last reply id forum meta
722 * @uses bbp_update_forum_last_active_id() To update the forum last active id
723 * @uses bbp_get_forum_last_active_id() To get the forum last active id
724 * @uses bbp_update_forum_last_active_time() To update the forum last active time
725 * @uses bbp_update_forum_reply_count() To update the forum reply count
726 */
727 function bbp_update_reply_walker( $reply_id, $last_active_time = '', $forum_id = 0, $topic_id = 0, $refresh = true ) {
728
729 // Verify the reply ID
730 $reply_id = bbp_get_reply_id( $reply_id );
731
732 // Reply was passed
733 if ( !empty( $reply_id ) ) {
734
735 // Get the topic ID if none was passed
736 if ( empty( $topic_id ) ) {
737 $topic_id = bbp_get_reply_topic_id( $reply_id );
738 }
739
740 // Get the forum ID if none was passed
741 if ( empty( $forum_id ) ) {
742 $forum_id = bbp_get_reply_forum_id( $reply_id );
743 }
744 }
745
746 // Set the active_id based on topic_id/reply_id
747 $active_id = empty( $reply_id ) ? $topic_id : $reply_id;
748
749 // Setup ancestors array to walk up
750 $ancestors = array_values( array_unique( array_merge( array( $topic_id, $forum_id ), get_post_ancestors( $topic_id ) ) ) );
751
752 // If we want a full refresh, unset any of the possibly passed variables
753 if ( true == $refresh )
754 $forum_id = $topic_id = $reply_id = $active_id = $last_active_time = 0;
755
756 // Walk up ancestors
757 foreach ( $ancestors as $ancestor ) {
758
759 // Reply meta relating to most recent reply
760 if ( bbp_is_reply( $ancestor ) ) {
761 // @todo - hierarchical replies
762
763 // Topic meta relating to most recent reply
764 } elseif ( bbp_is_topic( $ancestor ) ) {
765
766 // Last reply and active ID's
767 bbp_update_topic_last_reply_id ( $ancestor, $reply_id );
768 bbp_update_topic_last_active_id( $ancestor, $active_id );
769
770 // Get the last active time if none was passed
771 $topic_last_active_time = $last_active_time;
772 if ( empty( $last_active_time ) ) {
773 $topic_last_active_time = get_post_field( 'post_date', bbp_get_topic_last_active_id( $ancestor ) );
774 }
775
776 // Only update if reply is published
777 if ( bbp_is_reply_published( $reply_id ) ) {
778 bbp_update_topic_last_active_time( $ancestor, $topic_last_active_time );
779 }
780
781 // Counts
782 bbp_update_topic_voice_count ( $ancestor );
783 bbp_update_topic_reply_count ( $ancestor );
784 bbp_update_topic_reply_count_hidden( $ancestor );
785
786 // Forum meta relating to most recent topic
787 } elseif ( bbp_is_forum( $ancestor ) ) {
788
789 // Last topic and reply ID's
790 bbp_update_forum_last_topic_id( $ancestor, $topic_id );
791 bbp_update_forum_last_reply_id( $ancestor, $reply_id );
792
793 // Last Active
794 bbp_update_forum_last_active_id( $ancestor, $active_id );
795
796 // Get the last active time if none was passed
797 $forum_last_active_time = $last_active_time;
798 if ( empty( $last_active_time ) ) {
799 $forum_last_active_time = get_post_field( 'post_date', bbp_get_forum_last_active_id( $ancestor ) );
800 }
801
802 // Only update if reply is published
803 if ( bbp_is_reply_published( $reply_id ) ) {
804 bbp_update_forum_last_active_time( $ancestor, $forum_last_active_time );
805 }
806
807 // Counts
808 bbp_update_forum_reply_count( $ancestor );
809 }
810 }
811 }
812
813 /** Reply Updaters ************************************************************/
814
815 /**
816 * Update the reply with its forum id it is in
817 *
818 * @since bbPress (r2855)
819 *
820 * @param int $reply_id Optional. Reply id to update
821 * @param int $forum_id Optional. Forum id
822 * @uses bbp_get_reply_id() To get the reply id
823 * @uses bbp_get_forum_id() To get the forum id
824 * @uses get_post_ancestors() To get the reply's forum
825 * @uses get_post_field() To get the post type of the post
826 * @uses update_post_meta() To update the reply forum id meta
827 * @uses apply_filters() Calls 'bbp_update_reply_forum_id' with the forum id
828 * and reply id
829 * @return bool Reply's forum id
830 */
831 function bbp_update_reply_forum_id( $reply_id = 0, $forum_id = 0 ) {
832
833 // Validation
834 $reply_id = bbp_get_reply_id( $reply_id );
835 $forum_id = bbp_get_forum_id( $forum_id );
836
837 // If no forum_id was passed, walk up ancestors and look for forum type
838 if ( empty( $forum_id ) ) {
839
840 // Get ancestors
841 $ancestors = get_post_ancestors( $reply_id );
842
843 // Loop through ancestors
844 foreach ( $ancestors as $ancestor ) {
845
846 // Get first parent that is a forum
847 if ( get_post_field( 'post_type', $ancestor ) == bbp_get_forum_post_type() ) {
848 $forum_id = $ancestor;
849
850 // Found a forum, so exit the loop and continue
851 continue;
852 }
853 }
854 }
855
856 // Update the forum ID
857 bbp_update_forum_id( $reply_id, $forum_id );
858
859 return apply_filters( 'bbp_update_reply_forum_id', (int) $forum_id, $reply_id );
860 }
861
862 /**
863 * Update the reply with its topic id it is in
864 *
865 * @since bbPress (r2855)
866 *
867 * @param int $reply_id Optional. Reply id to update
868 * @param int $topic_id Optional. Topic id
869 * @uses bbp_get_reply_id() To get the reply id
870 * @uses bbp_get_topic_id() To get the topic id
871 * @uses get_post_ancestors() To get the reply's topic
872 * @uses get_post_field() To get the post type of the post
873 * @uses update_post_meta() To update the reply topic id meta
874 * @uses apply_filters() Calls 'bbp_update_reply_topic_id' with the topic id
875 * and reply id
876 * @return bool Reply's topic id
877 */
878 function bbp_update_reply_topic_id( $reply_id = 0, $topic_id = 0 ) {
879
880 // Validation
881 $reply_id = bbp_get_reply_id( $reply_id );
882 $topic_id = bbp_get_topic_id( $topic_id );
883
884 // If no topic_id was passed, walk up ancestors and look for topic type
885 if ( empty( $topic_id ) ) {
886
887 // Get ancestors
888 $ancestors = get_post_ancestors( $reply_id );
889
890 // Loop through ancestors
891 foreach ( $ancestors as $ancestor ) {
892
893 // Get first parent that is a forum
894 if ( get_post_field( 'post_type', $ancestor ) == bbp_get_topic_post_type() ) {
895 $topic_id = $ancestor;
896
897 // Found a forum, so exit the loop and continue
898 continue;
899 }
900 }
901 }
902
903 // Update the topic ID
904 bbp_update_topic_id( $reply_id, $topic_id );
905
906 return apply_filters( 'bbp_update_reply_topic_id', (int) $topic_id, $reply_id );
907 }
908
909 /**
910 * Update the revision log of the reply
911 *
912 * @since bbPress (r2782)
913 *
914 * @param mixed $args Supports these args:
915 * - reply_id: reply id
916 * - author_id: Author id
917 * - reason: Reason for editing
918 * - revision_id: Revision id
919 * @uses bbp_get_reply_id() To get the reply id
920 * @uses bbp_get_user_id() To get the user id
921 * @uses bbp_format_revision_reason() To format the reason
922 * @uses bbp_get_reply_raw_revision_log() To get the raw reply revision log
923 * @uses update_post_meta() To update the reply revision log meta
924 * @return mixed False on failure, true on success
925 */
926 function bbp_update_reply_revision_log( $args = '' ) {
927 $defaults = array (
928 'reason' => '',
929 'reply_id' => 0,
930 'author_id' => 0,
931 'revision_id' => 0
932 );
933
934 $r = bbp_parse_args( $args, $defaults, 'update_reply_revision_log' );
935 extract( $r );
936
937 // Populate the variables
938 $reason = bbp_format_revision_reason( $reason );
939 $reply_id = bbp_get_reply_id( $reply_id );
940 $author_id = bbp_get_user_id ( $author_id, false, true );
941 $revision_id = (int) $revision_id;
942
943 // Get the logs and append the new one to those
944 $revision_log = bbp_get_reply_raw_revision_log( $reply_id );
945 $revision_log[$revision_id] = array( 'author' => $author_id, 'reason' => $reason );
946
947 // Finally, update
948 update_post_meta( $reply_id, '_bbp_revision_log', $revision_log );
949
950 return apply_filters( 'bbp_update_reply_revision_log', $revision_log, $reply_id );
951 }
952
953 /** Reply Actions *************************************************************/
954
955 /**
956 * Handles the front end spamming/unspamming and trashing/untrashing/deleting of
957 * replies
958 *
959 * @since bbPress (r2740)
960 *
961 * @uses bbp_get_reply() To get the reply
962 * @uses current_user_can() To check if the user is capable of editing or
963 * deleting the reply
964 * @uses check_ajax_referer() To verify the nonce and check the referer
965 * @uses bbp_get_reply_post_type() To get the reply post type
966 * @uses bbp_is_reply_spam() To check if the reply is marked as spam
967 * @uses bbp_spam_reply() To make the reply as spam
968 * @uses bbp_unspam_reply() To unmark the reply as spam
969 * @uses wp_trash_post() To trash the reply
970 * @uses wp_untrash_post() To untrash the reply
971 * @uses wp_delete_post() To delete the reply
972 * @uses do_action() Calls 'bbp_toggle_reply_handler' with success, post data
973 * and action
974 * @uses bbp_get_reply_url() To get the reply url
975 * @uses add_query_arg() To add custom args to the reply url
976 * @uses wp_safe_redirect() To redirect to the reply
977 * @uses bbPress::errors:add() To log the error messages
978 */
979 function bbp_toggle_reply_handler() {
980
981 // Bail if not a GET action
982 if ( 'GET' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) )
983 return;
984
985 // Bail if required GET actions aren't passed
986 if ( empty( $_GET['reply_id'] ) || empty( $_GET['action'] ) )
987 return;
988
989 // Setup possible get actions
990 $possible_actions = array(
991 'bbp_toggle_reply_spam',
992 'bbp_toggle_reply_trash'
993 );
994
995 // Bail if actions aren't meant for this function
996 if ( !in_array( $_GET['action'], $possible_actions ) )
997 return;
998
999 $failure = ''; // Empty failure string
1000 $view_all = false; // Assume not viewing all
1001 $action = $_GET['action']; // What action is taking place?
1002 $reply_id = (int) $_GET['reply_id']; // What's the reply id?
1003 $success = false; // Flag
1004 $post_data = array( 'ID' => $reply_id ); // Prelim array
1005
1006 // Make sure reply exists
1007 $reply = bbp_get_reply( $reply_id );
1008 if ( empty( $reply ) )
1009 return;
1010
1011 // What is the user doing here?
1012 if ( !current_user_can( 'edit_reply', $reply->ID ) || ( 'bbp_toggle_reply_trash' == $action && !current_user_can( 'delete_reply', $reply->ID ) ) ) {
1013 bbp_add_error( 'bbp_toggle_reply_permission', __( '<strong>ERROR:</strong> You do not have the permission to do that!', 'bbpress' ) );
1014 return;
1015 }
1016
1017 // What action are we trying to perform?
1018 switch ( $action ) {
1019
1020 // Toggle spam
1021 case 'bbp_toggle_reply_spam' :
1022 check_ajax_referer( 'spam-reply_' . $reply_id );
1023
1024 $is_spam = bbp_is_reply_spam( $reply_id );
1025 $success = $is_spam ? bbp_unspam_reply( $reply_id ) : bbp_spam_reply( $reply_id );
1026 $failure = $is_spam ? __( '<strong>ERROR</strong>: There was a problem unmarking the reply as spam!', 'bbpress' ) : __( '<strong>ERROR</strong>: There was a problem marking the reply as spam!', 'bbpress' );
1027 $view_all = !$is_spam;
1028
1029 break;
1030
1031 // Toggle trash
1032 case 'bbp_toggle_reply_trash' :
1033
1034 $sub_action = in_array( $_GET['sub_action'], array( 'trash', 'untrash', 'delete' ) ) ? $_GET['sub_action'] : false;
1035
1036 if ( empty( $sub_action ) )
1037 break;
1038
1039 switch ( $sub_action ) {
1040 case 'trash':
1041 check_ajax_referer( 'trash-' . bbp_get_reply_post_type() . '_' . $reply_id );
1042
1043 $view_all = true;
1044 $success = wp_trash_post( $reply_id );
1045 $failure = __( '<strong>ERROR</strong>: There was a problem trashing the reply!', 'bbpress' );
1046
1047 break;
1048
1049 case 'untrash':
1050 check_ajax_referer( 'untrash-' . bbp_get_reply_post_type() . '_' . $reply_id );
1051
1052 $success = wp_untrash_post( $reply_id );
1053 $failure = __( '<strong>ERROR</strong>: There was a problem untrashing the reply!', 'bbpress' );
1054
1055 break;
1056
1057 case 'delete':
1058 check_ajax_referer( 'delete-' . bbp_get_reply_post_type() . '_' . $reply_id );
1059
1060 $success = wp_delete_post( $reply_id );
1061 $failure = __( '<strong>ERROR</strong>: There was a problem deleting the reply!', 'bbpress' );
1062
1063 break;
1064 }
1065
1066 break;
1067 }
1068
1069 // Do additional reply toggle actions
1070 do_action( 'bbp_toggle_reply_handler', $success, $post_data, $action );
1071
1072 // No errors
1073 if ( ( false != $success ) && !is_wp_error( $success ) ) {
1074
1075 /** Redirect **********************************************************/
1076
1077 // Redirect to
1078 $redirect_to = !empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
1079
1080 // Get the reply URL
1081 $reply_url = bbp_get_reply_url( $reply_id, $redirect_to );
1082
1083 // Add view all if needed
1084 if ( !empty( $view_all ) )
1085 $reply_url = bbp_add_view_all( $reply_url, true );
1086
1087 // Redirect back to reply
1088 wp_safe_redirect( $reply_url );
1089
1090 // For good measure
1091 exit();
1092
1093 // Handle errors
1094 } else {
1095 bbp_add_error( 'bbp_toggle_reply', $failure );
1096 }
1097 }
1098
1099 /** Reply Actions *************************************************************/
1100
1101 /**
1102 * Marks a reply as spam
1103 *
1104 * @since bbPress (r2740)
1105 *
1106 * @param int $reply_id Reply id
1107 * @uses wp_get_single_post() To get the reply
1108 * @uses do_action() Calls 'bbp_spam_reply' with the reply ID
1109 * @uses add_post_meta() To add the previous status to a meta
1110 * @uses wp_insert_post() To insert the updated post
1111 * @uses do_action() Calls 'bbp_spammed_reply' with the reply ID
1112 * @return mixed False or {@link WP_Error} on failure, reply id on success
1113 */
1114 function bbp_spam_reply( $reply_id = 0 ) {
1115
1116 // Get reply
1117 $reply = wp_get_single_post( $reply_id, ARRAY_A );
1118 if ( empty( $reply ) )
1119 return $reply;
1120
1121 // Bail if already spam
1122 if ( bbp_get_spam_status_id() == $reply['post_status'] )
1123 return false;
1124
1125 // Execute pre spam code
1126 do_action( 'bbp_spam_reply', $reply_id );
1127
1128 // Add the original post status as post meta for future restoration
1129 add_post_meta( $reply_id, '_bbp_spam_meta_status', $reply['post_status'] );
1130
1131 // Set post status to spam
1132 $reply['post_status'] = bbp_get_spam_status_id();
1133
1134 // No revisions
1135 remove_action( 'pre_post_update', 'wp_save_post_revision' );
1136
1137 // Update the reply
1138 $reply_id = wp_insert_post( $reply );
1139
1140 // Execute post spam code
1141 do_action( 'bbp_spammed_reply', $reply_id );
1142
1143 // Return reply_id
1144 return $reply_id;
1145 }
1146
1147 /**
1148 * Unspams a reply
1149 *
1150 * @since bbPress (r2740)
1151 *
1152 * @param int $reply_id Reply id
1153 * @uses wp_get_single_post() To get the reply
1154 * @uses do_action() Calls 'bbp_unspam_reply' with the reply ID
1155 * @uses get_post_meta() To get the previous status meta
1156 * @uses delete_post_meta() To delete the previous status meta
1157 * @uses wp_insert_post() To insert the updated post
1158 * @uses do_action() Calls 'bbp_unspammed_reply' with the reply ID
1159 * @return mixed False or {@link WP_Error} on failure, reply id on success
1160 */
1161 function bbp_unspam_reply( $reply_id = 0 ) {
1162
1163 // Get reply
1164 $reply = wp_get_single_post( $reply_id, ARRAY_A );
1165 if ( empty( $reply ) )
1166 return $reply;
1167
1168 // Bail if already not spam
1169 if ( bbp_get_spam_status_id() != $reply['post_status'] )
1170 return false;
1171
1172 // Execute pre unspam code
1173 do_action( 'bbp_unspam_reply', $reply_id );
1174
1175 // Get pre spam status
1176 $reply['post_status'] = get_post_meta( $reply_id, '_bbp_spam_meta_status', true );
1177
1178 // Delete pre spam meta
1179 delete_post_meta( $reply_id, '_bbp_spam_meta_status' );
1180
1181 // No revisions
1182 remove_action( 'pre_post_update', 'wp_save_post_revision' );
1183
1184 // Update the reply
1185 $reply_id = wp_insert_post( $reply );
1186
1187 // Execute post unspam code
1188 do_action( 'bbp_unspammed_reply', $reply_id );
1189
1190 // Return reply_id
1191 return $reply_id;
1192 }
1193
1194 /** Before Delete/Trash/Untrash ***********************************************/
1195
1196 /**
1197 * Called before deleting a reply
1198 *
1199 * @uses bbp_get_reply_id() To get the reply id
1200 * @uses bbp_is_reply() To check if the passed id is a reply
1201 * @uses do_action() Calls 'bbp_delete_reply' with the reply id
1202 */
1203 function bbp_delete_reply( $reply_id = 0 ) {
1204 $reply_id = bbp_get_reply_id( $reply_id );
1205
1206 if ( empty( $reply_id ) || !bbp_is_reply( $reply_id ) )
1207 return false;
1208
1209 do_action( 'bbp_delete_reply', $reply_id );
1210 }
1211
1212 /**
1213 * Called before trashing a reply
1214 *
1215 * @uses bbp_get_reply_id() To get the reply id
1216 * @uses bbp_is_reply() To check if the passed id is a reply
1217 * @uses do_action() Calls 'bbp_trash_reply' with the reply id
1218 */
1219 function bbp_trash_reply( $reply_id = 0 ) {
1220 $reply_id = bbp_get_reply_id( $reply_id );
1221
1222 if ( empty( $reply_id ) || !bbp_is_reply( $reply_id ) )
1223 return false;
1224
1225 do_action( 'bbp_trash_reply', $reply_id );
1226 }
1227
1228 /**
1229 * Called before untrashing (restoring) a reply
1230 *
1231 * @uses bbp_get_reply_id() To get the reply id
1232 * @uses bbp_is_reply() To check if the passed id is a reply
1233 * @uses do_action() Calls 'bbp_unstrash_reply' with the reply id
1234 */
1235 function bbp_untrash_reply( $reply_id = 0 ) {
1236 $reply_id = bbp_get_reply_id( $reply_id );
1237
1238 if ( empty( $reply_id ) || !bbp_is_reply( $reply_id ) )
1239 return false;
1240
1241 do_action( 'bbp_untrash_reply', $reply_id );
1242 }
1243
1244 /** After Delete/Trash/Untrash ************************************************/
1245
1246 /**
1247 * Called after deleting a reply
1248 *
1249 * @uses bbp_get_reply_id() To get the reply id
1250 * @uses bbp_is_reply() To check if the passed id is a reply
1251 * @uses do_action() Calls 'bbp_deleted_reply' with the reply id
1252 */
1253 function bbp_deleted_reply( $reply_id = 0 ) {
1254 $reply_id = bbp_get_reply_id( $reply_id );
1255
1256 if ( empty( $reply_id ) || !bbp_is_reply( $reply_id ) )
1257 return false;
1258
1259 do_action( 'bbp_deleted_reply', $reply_id );
1260 }
1261
1262 /**
1263 * Called after trashing a reply
1264 *
1265 * @uses bbp_get_reply_id() To get the reply id
1266 * @uses bbp_is_reply() To check if the passed id is a reply
1267 * @uses do_action() Calls 'bbp_trashed_reply' with the reply id
1268 */
1269 function bbp_trashed_reply( $reply_id = 0 ) {
1270 $reply_id = bbp_get_reply_id( $reply_id );
1271
1272 if ( empty( $reply_id ) || !bbp_is_reply( $reply_id ) )
1273 return false;
1274
1275 do_action( 'bbp_trashed_reply', $reply_id );
1276 }
1277
1278 /**
1279 * Called after untrashing (restoring) a reply
1280 *
1281 * @uses bbp_get_reply_id() To get the reply id
1282 * @uses bbp_is_reply() To check if the passed id is a reply
1283 * @uses do_action() Calls 'bbp_untrashed_reply' with the reply id
1284 */
1285 function bbp_untrashed_reply( $reply_id = 0 ) {
1286 $reply_id = bbp_get_reply_id( $reply_id );
1287
1288 if ( empty( $reply_id ) || !bbp_is_reply( $reply_id ) )
1289 return false;
1290
1291 do_action( 'bbp_untrashed_reply', $reply_id );
1292 }
1293
1294 /** Settings ******************************************************************/
1295
1296 /**
1297 * Return the replies per page setting
1298 *
1299 * @since bbPress (r3540)
1300 *
1301 * @uses get_option() To get the setting
1302 * @uses apply_filters() To allow the return value to be manipulated
1303 * @return int
1304 */
1305 function bbp_get_replies_per_page() {
1306
1307 // The default per setting
1308 $default = 15;
1309
1310 // Get database option and cast as integer
1311 $per = $retval = (int) get_option( '_bbp_replies_per_page', $default );
1312
1313 // If return val is empty, set it to default
1314 if ( empty( $retval ) )
1315 $retval = $default;
1316
1317 // Filter and return
1318 return (int) apply_filters( 'bbp_get_replies_per_page', $retval, $per );
1319 }
1320
1321 /**
1322 * Return the replies per RSS page setting
1323 *
1324 * @since bbPress (r3540)
1325 *
1326 * @uses get_option() To get the setting
1327 * @uses apply_filters() To allow the return value to be manipulated
1328 * @return int
1329 */
1330 function bbp_get_replies_per_rss_page() {
1331
1332 // The default per setting
1333 $default = 25;
1334
1335 // Get database option and cast as integer
1336 $per = $retval = (int) get_option( '_bbp_replies_per_rss_page', $default );
1337
1338 // If return val is empty, set it to default
1339 if ( empty( $retval ) )
1340 $retval = $default;
1341
1342 // Filter and return
1343 return (int) apply_filters( 'bbp_get_replies_per_rss_page', $retval, $per );
1344 }
1345
1346 /** Autoembed *****************************************************************/
1347
1348 /**
1349 * Check if autoembeds are enabled and hook them in if so
1350 *
1351 * @since bbPress (r3752)
1352 * @global WP_Embed $wp_embed
1353 */
1354 function bbp_reply_content_autoembed() {
1355 global $wp_embed;
1356
1357 if ( bbp_use_autoembed() && is_a( $wp_embed, 'WP_Embed' ) ) {
1358 add_filter( 'bbp_get_reply_content', array( $wp_embed, 'autoembed' ), 8 );
1359 }
1360 }
1361
1362 /** Feeds *********************************************************************/
1363
1364 /**
1365 * Output an RSS2 feed of replies, based on the query passed.
1366 *
1367 * @since bbPress (r3171)
1368 *
1369 * @uses bbp_version()
1370 * @uses bbp_is_single_topic()
1371 * @uses bbp_user_can_view_forum()
1372 * @uses bbp_get_topic_forum_id()
1373 * @uses bbp_show_load_topic()
1374 * @uses bbp_topic_permalink()
1375 * @uses bbp_topic_title()
1376 * @uses bbp_get_topic_reply_count()
1377 * @uses bbp_topic_content()
1378 * @uses bbp_has_replies()
1379 * @uses bbp_replies()
1380 * @uses bbp_the_reply()
1381 * @uses bbp_reply_url()
1382 * @uses bbp_reply_title()
1383 * @uses bbp_reply_content()
1384 * @uses get_wp_title_rss()
1385 * @uses get_option()
1386 * @uses bloginfo_rss
1387 * @uses self_link()
1388 * @uses the_author()
1389 * @uses get_post_time()
1390 * @uses rss_enclosure()
1391 * @uses do_action()
1392 * @uses apply_filters()
1393 *
1394 * @param array $replies_query
1395 */
1396 function bbp_display_replies_feed_rss2( $replies_query = array() ) {
1397
1398 // User cannot access forum this topic is in
1399 if ( bbp_is_single_topic() && !bbp_user_can_view_forum( array( 'forum_id' => bbp_get_topic_forum_id() ) ) )
1400 return;
1401
1402 // Adjust the title based on context
1403 if ( bbp_is_single_topic() && bbp_user_can_view_forum( array( 'forum_id' => bbp_get_topic_forum_id() ) ) )
1404 $title = apply_filters( 'wp_title_rss', get_wp_title_rss( ' &#187; ' ) );
1405 elseif ( !bbp_show_lead_topic() )
1406 $title = ' &#187; ' . __( 'All Posts', 'bbpress' );
1407 else
1408 $title = ' &#187; ' . __( 'All Replies', 'bbpress' );
1409
1410 // Display the feed
1411 header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
1412 header( 'Status: 200 OK' );
1413 echo '<?xml version="1.0" encoding="' . get_option( 'blog_charset' ) . '"?' . '>'; ?>
1414
1415 <rss version="2.0"
1416 xmlns:content="http://purl.org/rss/1.0/modules/content/"
1417 xmlns:wfw="http://wellformedweb.org/CommentAPI/"
1418 xmlns:dc="http://purl.org/dc/elements/1.1/"
1419 xmlns:atom="http://www.w3.org/2005/Atom"
1420
1421 <?php do_action( 'bbp_feed' ); ?>
1422 >
1423
1424 <channel>
1425 <title><?php bloginfo_rss('name'); echo $title; ?></title>
1426 <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
1427 <link><?php self_link(); ?></link>
1428 <description><?php //?></description>
1429 <pubDate><?php echo mysql2date( 'D, d M Y H:i:s O', '', false ); ?></pubDate>
1430 <generator>http://bbpress.org/?v=<?php bbp_version(); ?></generator>
1431 <language><?php echo get_option( 'rss_language' ); ?></language>
1432
1433 <?php do_action( 'bbp_feed_head' ); ?>
1434
1435 <?php if ( bbp_is_single_topic() ) : ?>
1436 <?php if ( bbp_user_can_view_forum( array( 'forum_id' => bbp_get_topic_forum_id() ) ) ) : ?>
1437 <?php if ( bbp_show_lead_topic() ) : ?>
1438
1439 <item>
1440 <guid><?php bbp_topic_permalink(); ?></guid>
1441 <title><![CDATA[<?php bbp_topic_title(); ?>]]></title>
1442 <link><?php bbp_topic_permalink(); ?></link>
1443 <pubDate><?php echo mysql2date( 'D, d M Y H:i:s +0000', get_post_time( 'Y-m-d H:i:s', true ), false ); ?></pubDate>
1444 <dc:creator><?php the_author(); ?></dc:creator>
1445
1446 <description>
1447 <![CDATA[
1448 <p><?php printf( __( 'Replies: %s', 'bbpress' ), bbp_get_topic_reply_count() ); ?></p>
1449 <?php bbp_topic_content(); ?>
1450 ]]>
1451 </description>
1452
1453 <?php rss_enclosure(); ?>
1454
1455 <?php do_action( 'bbp_feed_item' ); ?>
1456
1457 </item>
1458
1459 <?php endif; ?>
1460 <?php endif; ?>
1461 <?php endif; ?>
1462
1463 <?php if ( bbp_has_replies( $replies_query ) ) : ?>
1464 <?php while ( bbp_replies() ) : bbp_the_reply(); ?>
1465
1466 <item>
1467 <guid><?php bbp_reply_url(); ?></guid>
1468 <title><![CDATA[<?php bbp_reply_title(); ?>]]></title>
1469 <link><?php bbp_reply_url(); ?></link>
1470 <pubDate><?php echo mysql2date( 'D, d M Y H:i:s +0000', get_post_time( 'Y-m-d H:i:s', true ), false ); ?></pubDate>
1471 <dc:creator><?php the_author() ?></dc:creator>
1472
1473 <description>
1474 <![CDATA[
1475 <?php bbp_reply_content(); ?>
1476 ]]>
1477 </description>
1478
1479 <?php rss_enclosure(); ?>
1480
1481 <?php do_action( 'bbp_feed_item' ); ?>
1482
1483 </item>
1484
1485 <?php endwhile; ?>
1486 <?php endif; ?>
1487
1488 <?php do_action( 'bbp_feed_footer' ); ?>
1489
1490 </channel>
1491 </rss>
1492
1493 <?php
1494
1495 // We're done here
1496 exit();
1497 }
1498
1499 /** Permissions ***************************************************************/
1500
1501 /**
1502 * Redirect if unathorized user is attempting to edit a reply
1503 *
1504 * @since bbPress (r3605)
1505 *
1506 * @uses bbp_is_reply_edit()
1507 * @uses current_user_can()
1508 * @uses bbp_get_topic_id()
1509 * @uses wp_safe_redirect()
1510 * @uses bbp_get_topic_permalink()
1511 */
1512 function bbp_check_reply_edit() {
1513
1514 // Bail if not editing a topic
1515 if ( !bbp_is_reply_edit() )
1516 return;
1517
1518 // User cannot edit topic, so redirect back to reply
1519 if ( !current_user_can( 'edit_reply', bbp_get_reply_id() ) ) {
1520 wp_safe_redirect( bbp_get_reply_url() );
1521 exit();
1522 }
1523 }
1524
1525 /** Reply Position ************************************************************/
1526
1527 /**
1528 * Update the position of the reply.
1529 *
1530 * The reply position is stored in the menu_order column of the posts table.
1531 * This is done to prevent using a meta_query to retrieve posts in the proper
1532 * freshness order. By updating the menu_order accordingly, we're able to
1533 * leverage core WordPress query ordering much more effectively.
1534 *
1535 * @since bbPress (r3933)
1536 *
1537 * @global type $wpdb
1538 * @param type $reply_id
1539 * @param type $reply_position
1540 * @return mixed
1541 */
1542 function bbp_update_reply_position( $reply_id = 0, $reply_position = 0 ) {
1543
1544 // Bail if reply_id is empty
1545 $reply_id = bbp_get_reply_id( $reply_id );
1546 if ( empty( $reply_id ) )
1547 return false;
1548
1549 // If no position was passed, get it from the db and update the menu_order
1550 if ( empty( $reply_position ) ) {
1551 $reply_position = bbp_get_reply_position_raw( $reply_id, bbp_get_reply_topic_id( $reply_id ) );
1552 }
1553
1554 // Update the replies' 'menp_order' with the reply position
1555 global $wpdb;
1556 $wpdb->update( $wpdb->posts, array( 'menu_order' => $reply_position ), array( 'ID' => $reply_id ) );
1557
1558 return (int) $reply_position;
1559 }
1560
1561 /**
1562 * Get the position of a reply by querying the DB directly for the replies
1563 * of a given topic.
1564 *
1565 * @since bbPress (r3933)
1566 *
1567 * @param int $reply_id
1568 * @param int $topic_id
1569 */
1570 function bbp_get_reply_position_raw( $reply_id = 0, $topic_id = 0 ) {
1571
1572 // Get required data
1573 $reply_id = bbp_get_reply_id( $reply_id );
1574 $topic_id = !empty( $topic_id ) ? bbp_get_topic_id( $topic_id ) : bbp_get_reply_topic_id( $reply_id );
1575 $reply_position = 0;
1576
1577 // If reply is actually the first post in a topic, return 0
1578 if ( $reply_id != $topic_id ) {
1579
1580 // Make sure the topic has replies before running another query
1581 $reply_count = bbp_get_topic_reply_count( $topic_id );
1582 if ( !empty( $reply_count ) ) {
1583
1584 // Get reply id's
1585 $topic_replies = bbp_get_all_child_ids( $topic_id, bbp_get_reply_post_type() );
1586 if ( !empty( $topic_replies ) ) {
1587
1588 // Reverse replies array and search for current reply position
1589 $topic_replies = array_reverse( $topic_replies );
1590 $reply_position = array_search( (string) $reply_id, $topic_replies );
1591
1592 // Bump the position to compensate for the lead topic post
1593 $reply_position++;
1594 }
1595 }
1596 }
1597
1598 return (int) $reply_position;
1599 }
1600