PluginProbe
bbPress / 2.1
bbPress v2.1
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 2.2.2 All 71 releases
bbpress / bbp-includes / bbp-reply-functions.php

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

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