PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / trunk
Forumax – AI Powered Advanced Community Forum Plugin vtrunk
2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 trunk 1.0.8 1.1.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 2.0.0 2.1.0 All 29 releases
bbp-core / lib / bbpress / includes / replies / template.php

template.php in Forumax – AI Powered Advanced Community Forum Plugin trunk, at lib/bbpress/includes/replies/template.php

2,768 lines 79.5 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 Template Tags
5 *
6 * @package bbPress
7 * @subpackage TemplateTags
8 */
9
10 // Exit if accessed directly
11 defined( 'ABSPATH' ) || exit;
12
13 /** Post Type *****************************************************************/
14
15 /**
16 * Return the unique id of the custom post type for replies
17 *
18 * @since 2.0.0 bbPress (r2857)
19 *
20 */
21 function bbp_reply_post_type() {
22 echo bbp_get_reply_post_type();
23 }
24 /**
25 * Return the unique id of the custom post type for replies
26 *
27 * @since 2.0.0 bbPress (r2857)
28 *
29 * post type id
30 * @return string The unique reply post type id
31 */
32 function bbp_get_reply_post_type() {
33
34 // Filter & return
35 return apply_filters( 'bbp_get_reply_post_type', bbpress()->reply_post_type );
36 }
37
38 /**
39 * Return array of labels used by the reply post type
40 *
41 * @since 2.5.0 bbPress (r5129)
42 *
43 * @return array
44 */
45 function bbp_get_reply_post_type_labels() {
46
47 // Filter & return
48 return (array) apply_filters( 'bbp_get_reply_post_type_labels', array(
49 'name' => esc_attr__( 'Replies', 'bbpress' ),
50 'menu_name' => esc_attr__( 'Replies', 'bbpress' ),
51 'singular_name' => esc_attr_x( 'Reply', 'noun', 'bbpress' ),
52 'all_items' => esc_attr__( 'All Replies', 'bbpress' ),
53 'add_new' => esc_attr__( 'Add New', 'bbpress' ),
54 'add_new_item' => esc_attr__( 'Create New Reply', 'bbpress' ),
55 'edit' => esc_attr__( 'Edit', 'bbpress' ),
56 'edit_item' => esc_attr__( 'Edit Reply', 'bbpress' ),
57 'new_item' => esc_attr__( 'New Reply', 'bbpress' ),
58 'view' => esc_attr__( 'View Reply', 'bbpress' ),
59 'view_item' => esc_attr__( 'View Reply', 'bbpress' ),
60 'view_items' => esc_attr__( 'View Replies', 'bbpress' ),
61 'search_items' => esc_attr__( 'Search Replies', 'bbpress' ),
62 'not_found' => esc_attr__( 'No replies found', 'bbpress' ),
63 'not_found_in_trash' => esc_attr__( 'No replies found in Trash', 'bbpress' ),
64 'filter_items_list' => esc_attr__( 'Filter replies list', 'bbpress' ),
65 'items_list' => esc_attr__( 'Replies list', 'bbpress' ),
66 'items_list_navigation' => esc_attr__( 'Replies list navigation', 'bbpress' ),
67 'parent_item_colon' => esc_attr__( 'Parent Topic:', 'bbpress' ),
68 'archives' => esc_attr__( 'Forum Replies', 'bbpress' ),
69 'attributes' => esc_attr__( 'Reply Attributes', 'bbpress' ),
70 'insert_into_item' => esc_attr__( 'Insert into reply', 'bbpress' ),
71 'uploaded_to_this_item' => esc_attr__( 'Uploaded to this reply', 'bbpress' ),
72 'featured_image' => esc_attr__( 'Reply Image', 'bbpress' ),
73 'set_featured_image' => esc_attr__( 'Set reply image', 'bbpress' ),
74 'remove_featured_image' => esc_attr__( 'Remove reply image', 'bbpress' ),
75 'use_featured_image' => esc_attr__( 'Use as reply image', 'bbpress' ),
76 'item_published' => esc_attr__( 'Reply published.', 'bbpress' ),
77 'item_published_privately' => esc_attr__( 'Reply published privately.', 'bbpress' ),
78 'item_reverted_to_draft' => esc_attr__( 'Reply reverted to draft.', 'bbpress' ),
79 'item_scheduled' => esc_attr__( 'Reply scheduled.', 'bbpress' ),
80 'item_updated' => esc_attr__( 'Reply updated.', 'bbpress' )
81 ) );
82 }
83
84 /**
85 * Return array of reply post type rewrite settings
86 *
87 * @since 2.5.0 bbPress (r5129)
88 *
89 * @return array
90 */
91 function bbp_get_reply_post_type_rewrite() {
92
93 // Filter & return
94 return (array) apply_filters( 'bbp_get_reply_post_type_rewrite', array(
95 'slug' => bbp_get_reply_slug(),
96 'with_front' => false
97 ) );
98 }
99
100 /**
101 * Return array of features the reply post type supports
102 *
103 * @since 2.5.0 bbPress (r5129)
104 *
105 * @return array
106 */
107 function bbp_get_reply_post_type_supports() {
108
109 // Filter & return
110 return (array) apply_filters( 'bbp_get_reply_post_type_supports', array(
111 'title',
112 'editor',
113 'revisions'
114 ) );
115 }
116
117 /** Reply Loop Functions ******************************************************/
118
119 /**
120 * The main reply loop. WordPress makes this easy for us
121 *
122 * @since 2.0.0 bbPress (r2553)
123 *
124 * @param array $args All the arguments supported by {@link WP_Query}
125 * @return object Multidimensional array of reply information
126 */
127 function bbp_has_replies( $args = array() ) {
128
129 /** Defaults **************************************************************/
130
131 // Other defaults
132 $default_reply_search = bbp_sanitize_search_request( 'rs' );
133 $default_post_parent = ( bbp_is_single_topic() ) ? bbp_get_topic_id() : 'any';
134 $default_post_type = ( bbp_is_single_topic() && bbp_show_lead_topic() ) ? bbp_get_reply_post_type() : array( bbp_get_topic_post_type(), bbp_get_reply_post_type() );
135 $default_thread_replies = (bool) ( bbp_is_single_topic() && bbp_thread_replies() );
136
137 // Default query args
138 $default = array(
139 'post_type' => $default_post_type, // Only replies
140 'post_parent' => $default_post_parent, // Of this topic
141 'posts_per_page' => bbp_get_replies_per_page(), // This many
142 'paged' => bbp_get_paged(), // On this page
143 'orderby' => 'date', // Sorted by date
144 'order' => 'ASC', // Oldest to newest
145 'hierarchical' => $default_thread_replies, // Hierarchical replies
146 'ignore_sticky_posts' => true, // Stickies not supported
147 'update_post_term_cache' => false, // No terms to cache
148
149 // Conditionally prime the cache for all related posts
150 'update_post_family_cache' => true
151 );
152
153 // Only add 's' arg if searching for replies
154 // See https://bbpress.trac.wordpress.org/ticket/2607
155 if ( ! empty( $default_reply_search ) ) {
156 $default['s'] = $default_reply_search;
157 }
158
159 // What are the default allowed statuses (based on user caps)
160 if ( bbp_get_view_all( 'edit_others_replies' ) ) {
161
162 // Default view=all statuses
163 $post_statuses = array_keys( bbp_get_topic_statuses() );
164
165 // Add support for private status
166 if ( current_user_can( 'read_private_replies' ) ) {
167 $post_statuses[] = bbp_get_private_status_id();
168 }
169
170 // Join post statuses together
171 $default['post_status'] = $post_statuses;
172
173 // Lean on the 'perm' query var value of 'readable' to provide statuses
174 } else {
175 $default['perm'] = 'readable';
176 }
177
178 /** Setup *****************************************************************/
179
180 // Parse arguments against default values
181 $r = bbp_parse_args( $args, $default, 'has_replies' );
182
183 // Set posts_per_page value if replies are threaded
184 $replies_per_page = (int) $r['posts_per_page'];
185 if ( true === $r['hierarchical'] ) {
186 $r['posts_per_page'] = -1;
187 }
188
189 // Get bbPress
190 $bbp = bbpress();
191
192 // Call the query
193 $bbp->reply_query = new WP_Query( $r );
194
195 // Maybe prime the post author caches
196 if ( ! empty( $r['update_post_family_cache'] ) ) {
197 bbp_update_post_family_caches( $bbp->reply_query->posts );
198 }
199
200 // Add pagination values to query object
201 $bbp->reply_query->posts_per_page = (int) $replies_per_page;
202 $bbp->reply_query->paged = (int) $r['paged'];
203
204 // Never home, regardless of what parse_query says
205 $bbp->reply_query->is_home = false;
206
207 // Reset is_single if single topic
208 if ( bbp_is_single_topic() ) {
209 $bbp->reply_query->is_single = true;
210 }
211
212 // Only add reply to if query returned results
213 if ( ! empty( $bbp->reply_query->found_posts ) ) {
214
215 // Get reply to for each reply
216 foreach ( $bbp->reply_query->posts as &$post ) {
217
218 // Check for reply post type
219 if ( bbp_get_reply_post_type() === $post->post_type ) {
220 $reply_to = bbp_get_reply_to( $post->ID );
221
222 // Make sure it's a reply to a reply
223 if ( empty( $reply_to ) || ( bbp_get_reply_topic_id( $post->ID ) === $reply_to ) ) {
224 $reply_to = 0;
225 }
226
227 // Add reply_to to the post object so we can walk it later
228 $post->reply_to = $reply_to;
229 }
230 }
231 }
232
233 // Only add pagination if query returned results
234 if ( ! empty( $bbp->reply_query->found_posts ) && ! empty( $bbp->reply_query->posts_per_page ) ) {
235
236 // Figure out total pages
237 if ( true === $r['hierarchical'] ) {
238 $walker = new BBP_Walker_Reply();
239 $total_pages = ceil( $walker->get_number_of_root_elements( $bbp->reply_query->posts ) / $bbp->reply_query->posts_per_page );
240
241 // Pagination settings with filter.
242 $bbp_replies_pagination = apply_filters( 'bbp_replies_pagination', array(
243 'base' => bbp_get_replies_pagination_base( bbp_get_topic_id() ),
244 'total' => $total_pages,
245 'current' => $bbp->reply_query->paged
246 ) );
247
248 // Add pagination to query object.
249 $bbp->reply_query->pagination_links = bbp_paginate_links( $bbp_replies_pagination );
250 } else {
251
252 // Total for pagination boundaries
253 $total_pages = ( $bbp->reply_query->posts_per_page === $bbp->reply_query->found_posts )
254 ? 1
255 : ceil( $bbp->reply_query->found_posts / $bbp->reply_query->posts_per_page );
256
257 // Pagination settings with filter
258 $bbp_replies_pagination = apply_filters( 'bbp_replies_pagination', array(
259 'base' => bbp_get_replies_pagination_base( bbp_get_topic_id() ),
260 'total' => $total_pages,
261 'current' => $bbp->reply_query->paged
262 ) );
263
264 // Add pagination to query object
265 $bbp->reply_query->pagination_links = bbp_paginate_links( $bbp_replies_pagination );
266 }
267 }
268
269 // Filter & return
270 return apply_filters( 'bbp_has_replies', $bbp->reply_query->have_posts(), $bbp->reply_query );
271 }
272
273 /**
274 * Whether there are more replies available in the loop
275 *
276 * @since 2.0.0 bbPress (r2553)
277 *
278 * @return object Replies information
279 */
280 function bbp_replies() {
281
282 // Put into variable to check against next
283 $have_posts = bbpress()->reply_query->have_posts();
284
285 // Reset the post data when finished
286 if ( empty( $have_posts ) ) {
287 wp_reset_postdata();
288 }
289
290 return $have_posts;
291 }
292
293 /**
294 * Loads up the current reply in the loop
295 *
296 * @since 2.0.0 bbPress (r2553)
297 *
298 * @return object Reply information
299 */
300 function bbp_the_reply() {
301 return bbpress()->reply_query->the_post();
302 }
303
304 /**
305 * Output reply id
306 *
307 * @since 2.0.0 bbPress (r2553)
308 *
309 * @param $reply_id Optional. Used to check emptiness
310 */
311 function bbp_reply_id( $reply_id = 0 ) {
312 echo bbp_get_reply_id( $reply_id );
313 }
314 /**
315 * Return the id of the reply in a replies loop
316 *
317 * @since 2.0.0 bbPress (r2553)
318 *
319 * @param $reply_id Optional. Used to check emptiness
320 * @return int The reply id
321 */
322 function bbp_get_reply_id( $reply_id = 0 ) {
323 $bbp = bbpress();
324 $wp_query = bbp_get_wp_query();
325
326 // Easy empty checking
327 if ( ! empty( $reply_id ) && is_numeric( $reply_id ) ) {
328 $bbp_reply_id = $reply_id;
329
330 // Currently inside a replies loop
331 } elseif ( ! empty( $bbp->reply_query->in_the_loop ) && isset( $bbp->reply_query->post->ID ) ) {
332 $bbp_reply_id = $bbp->reply_query->post->ID;
333
334 // Currently inside a search loop
335 } elseif ( ! empty( $bbp->search_query->in_the_loop ) && isset( $bbp->search_query->post->ID ) && bbp_is_reply( $bbp->search_query->post->ID ) ) {
336 $bbp_reply_id = $bbp->search_query->post->ID;
337
338 // Currently viewing a forum
339 } elseif ( ( bbp_is_single_reply() || bbp_is_reply_edit() ) && ! empty( $bbp->current_reply_id ) ) {
340 $bbp_reply_id = $bbp->current_reply_id;
341
342 // Currently viewing a reply
343 } elseif ( ( bbp_is_single_reply() || bbp_is_reply_edit() ) && isset( $wp_query->post->ID ) ) {
344 $bbp_reply_id = $wp_query->post->ID;
345
346 // Fallback
347 } else {
348 $bbp_reply_id = 0;
349 }
350
351 // Filter & return
352 return (int) apply_filters( 'bbp_get_reply_id', $bbp_reply_id, $reply_id );
353 }
354
355 /**
356 * Gets a reply
357 *
358 * @since 2.0.0 bbPress (r2787)
359 *
360 * @param int|object $reply reply id or reply object
361 * @param string $output Optional. OBJECT, ARRAY_A, or ARRAY_N. Default = OBJECT
362 * @param string $filter Optional Sanitation filter. See {@link sanitize_post()}
363 * @return mixed Null if error or reply (in specified form) if success
364 */
365 function bbp_get_reply( $reply, $output = OBJECT, $filter = 'raw' ) {
366
367 // Maybe get ID from empty or int
368 if ( empty( $reply ) || is_numeric( $reply ) ) {
369 $reply = bbp_get_reply_id( $reply );
370 }
371
372 // Bail if no post object
373 $reply = get_post( $reply, OBJECT, $filter );
374 if ( empty( $reply ) ) {
375 return $reply;
376 }
377
378 // Bail if not correct post type
379 if ( $reply->post_type !== bbp_get_reply_post_type() ) {
380 return null;
381 }
382
383 // Default return value is OBJECT
384 $retval = $reply;
385
386 // Array A
387 if ( $output === ARRAY_A ) {
388 $retval = get_object_vars( $reply );
389
390 // Array N
391 } elseif ( $output === ARRAY_N ) {
392 $retval = array_values( get_object_vars( $reply ) );
393 }
394
395 // Filter & return
396 return apply_filters( 'bbp_get_reply', $retval, $reply, $output, $filter );
397 }
398
399 /**
400 * Output the link to the reply in the reply loop
401 *
402 * @since 2.0.0 bbPress (r2553)
403 *
404 * @param int $reply_id Optional. Reply id
405 */
406 function bbp_reply_permalink( $reply_id = 0 ) {
407 echo esc_url( bbp_get_reply_permalink( $reply_id ) );
408 }
409 /**
410 * Return the link to the reply
411 *
412 * @since 2.0.0 bbPress (r2553)
413 *
414 * @param int $reply_id Optional. Reply id
415 *
416 * @return string Permanent link to reply
417 */
418 function bbp_get_reply_permalink( $reply_id = 0 ) {
419 $reply_id = bbp_get_reply_id( $reply_id );
420
421 // Filter & return
422 return apply_filters( 'bbp_get_reply_permalink', get_permalink( $reply_id ), $reply_id );
423 }
424
425 /**
426 * Output the paginated url to the reply in the reply loop
427 *
428 * @since 2.0.0 bbPress (r2679)
429 *
430 * @param int $reply_id Optional. Reply id
431 */
432 function bbp_reply_url( $reply_id = 0 ) {
433 echo esc_url( bbp_get_reply_url( $reply_id ) );
434 }
435 /**
436 * Return the paginated url to the reply in the reply loop
437 *
438 * @since 2.0.0 bbPress (r2679)
439 *
440 * @param int $reply_id Optional. Reply id
441 * @param string $redirect_to Optional. Pass a redirect value for use with
442 * shortcodes and other fun things.
443 * @return string Link to reply relative to paginated topic
444 */
445 function bbp_get_reply_url( $reply_id = 0, $redirect_to = '' ) {
446
447 // Set needed variables
448 $reply_id = bbp_get_reply_id( $reply_id );
449 $topic_id = 0;
450
451 // Juggle reply & topic IDs for unpretty URL formatting
452 if ( bbp_is_reply( $reply_id ) ) {
453 $topic_id = bbp_get_reply_topic_id( $reply_id );
454 $topic = bbp_get_topic( $topic_id );
455 } elseif ( bbp_is_topic( $reply_id ) ) {
456 $topic_id = bbp_get_topic_id( $reply_id );
457 $topic = bbp_get_topic( $topic_id );
458 $reply_id = $topic_id;
459 }
460
461 // Hierarchical reply page
462 if ( bbp_thread_replies() ) {
463 $reply_page = 1;
464
465 // Standard reply page
466 } else {
467 $reply_page = ceil( (int) bbp_get_reply_position( $reply_id, $topic_id ) / (int) bbp_get_replies_per_page() );
468 }
469
470 // Get links & URLS
471 $reply_hash = '#post-' . $reply_id;
472 $topic_link = bbp_get_topic_permalink( $topic_id, $redirect_to );
473 $topic_url = remove_query_arg( 'view', $topic_link );
474
475 // Get vars needed to support pending topics with unpretty links
476 $has_slug = ! empty( $topic ) ? $topic->post_name : '';
477 $pretty = bbp_use_pretty_urls();
478 $published = bbp_is_topic_public( $topic_id );
479
480 // Don't include pagination if on first page
481 if ( 1 >= $reply_page ) {
482
483 // Pretty permalinks
484 if ( ! empty( $has_slug ) && ! empty( $pretty ) && ! empty( $published ) ) {
485 $url = user_trailingslashit( $topic_url ) . $reply_hash;
486
487 // Unpretty links
488 } else {
489 $url = $topic_url . $reply_hash;
490 }
491
492 // Include pagination
493 } else {
494
495 // Pretty permalinks
496 if ( ! empty( $has_slug ) && ! empty( $pretty ) && ! empty( $published ) ) {
497 $url = trailingslashit( $topic_url ) . trailingslashit( bbp_get_paged_slug() ) . $reply_page;
498 $url = user_trailingslashit( $url ) . $reply_hash;
499
500 // Unpretty links
501 } else {
502 $url = add_query_arg( 'paged', $reply_page, $topic_url ) . $reply_hash;
503 }
504 }
505
506 // Add topic view query arg back to end if it is set
507 if ( bbp_get_view_all() ) {
508 $url = bbp_add_view_all( $url );
509 }
510
511 // Filter & return
512 return apply_filters( 'bbp_get_reply_url', $url, $reply_id, $redirect_to );
513 }
514
515 /**
516 * Output the title of the reply
517 *
518 * @since 2.0.0 bbPress (r2553)
519 *
520 * @param int $reply_id Optional. Reply id
521 */
522 function bbp_reply_title( $reply_id = 0 ) {
523 echo bbp_get_reply_title( $reply_id );
524 }
525
526 /**
527 * Return the title of the reply
528 *
529 * @since 2.0.0 bbPress (r2553)
530 *
531 * @param int $reply_id Optional. Reply id
532 * @return string Title of reply
533 */
534 function bbp_get_reply_title( $reply_id = 0 ) {
535 $reply_id = bbp_get_reply_id( $reply_id );
536 $title = get_the_title( $reply_id );
537
538 // Filter & return
539 return apply_filters( 'bbp_get_reply_title', $title, $reply_id );
540 }
541
542 /**
543 * Get empty reply title fallback.
544 *
545 * @since 2.5.0 bbPress (r5177)
546 *
547 * @param string $post_title Required. Reply Title
548 * @param int $post_id Required. Reply ID
549 * @return string Title of reply
550 */
551 function bbp_get_reply_title_fallback( $post_title = '', $post_id = 0 ) {
552
553 // Bail if title not empty, or post is not a reply
554 if ( ! empty( $post_title ) || ! bbp_is_reply( $post_id ) ) {
555 return $post_title;
556 }
557
558 // Get reply topic title.
559 $topic_title = bbp_get_reply_topic_title( $post_id );
560
561 // Get empty reply title fallback.
562 $reply_title = sprintf( esc_html__( 'Reply To: %s', 'bbpress' ), $topic_title );
563
564 // Filter & return
565 return apply_filters( 'bbp_get_reply_title_fallback', $reply_title, $post_id, $topic_title );
566 }
567
568 /**
569 * Output the content of the reply
570 *
571 * @since 2.0.0 bbPress (r2553)
572 *
573 * @param int $reply_id Optional. reply id
574 */
575 function bbp_reply_content( $reply_id = 0 ) {
576 echo bbp_get_reply_content( $reply_id );
577 }
578 /**
579 * Return the content of the reply
580 *
581 * @since 2.0.0 bbPress (r2780)
582 *
583 * @param int $reply_id Optional. reply id
584 * @return string Content of the reply
585 */
586 function bbp_get_reply_content( $reply_id = 0 ) {
587 $reply_id = bbp_get_reply_id( $reply_id );
588
589 // Check if password is required
590 if ( post_password_required( $reply_id ) ) {
591 return get_the_password_form();
592 }
593
594 $content = get_post_field( 'post_content', $reply_id );
595
596 // Filter & return
597 return apply_filters( 'bbp_get_reply_content', $content, $reply_id );
598 }
599
600 /**
601 * Output the excerpt of the reply
602 *
603 * @since 2.0.0 bbPress (r2751)
604 *
605 * @param int $reply_id Optional. Reply id
606 * @param int $length Optional. Length of the excerpt. Defaults to 100 letters
607 */
608 function bbp_reply_excerpt( $reply_id = 0, $length = 100 ) {
609 echo bbp_get_reply_excerpt( $reply_id, $length );
610 }
611 /**
612 * Return the excerpt of the reply
613 *
614 * @since 2.0.0 bbPress (r2751)
615 *
616 * @param int $reply_id Optional. Reply id
617 * @param int $length Optional. Length of the excerpt. Defaults to 100
618 * letters
619 * @return string Reply Excerpt
620 */
621 function bbp_get_reply_excerpt( $reply_id = 0, $length = 100 ) {
622 $reply_id = bbp_get_reply_id( $reply_id );
623 $length = (int) $length;
624 $excerpt = get_post_field( 'post_excerpt', $reply_id );
625
626 if ( empty( $excerpt ) ) {
627 $excerpt = bbp_get_reply_content( $reply_id );
628 }
629
630 $excerpt = trim ( strip_tags( $excerpt ) );
631
632 // Multibyte support
633 if ( function_exists( 'mb_strlen' ) ) {
634 $excerpt_length = mb_strlen( $excerpt );
635 } else {
636 $excerpt_length = strlen( $excerpt );
637 }
638
639 if ( ! empty( $length ) && ( $excerpt_length > $length ) ) {
640 $excerpt = mb_substr( $excerpt, 0, $length - 1 );
641 $excerpt .= '&hellip;';
642 }
643
644 // Filter & return
645 return apply_filters( 'bbp_get_reply_excerpt', $excerpt, $reply_id, $length );
646 }
647
648 /**
649 * Output the post date and time of a reply
650 *
651 * @since 2.2.0 bbPress (r4155)
652 *
653 * @param int $reply_id Optional. Reply id.
654 * @param bool $humanize Optional. Humanize output using time_since
655 * @param bool $gmt Optional. Use GMT
656 */
657 function bbp_reply_post_date( $reply_id = 0, $humanize = false, $gmt = false ) {
658 echo bbp_get_reply_post_date( $reply_id, $humanize, $gmt );
659 }
660 /**
661 * Return the post date and time of a reply
662 *
663 * @since 2.2.0 bbPress (r4155)
664 *
665 * @param int $reply_id Optional. Reply id.
666 * @param bool $humanize Optional. Humanize output using time_since
667 * @param bool $gmt Optional. Use GMT
668 * @return string
669 */
670 function bbp_get_reply_post_date( $reply_id = 0, $humanize = false, $gmt = false ) {
671 $reply_id = bbp_get_reply_id( $reply_id );
672
673 // 4 days, 4 hours ago
674 if ( ! empty( $humanize ) ) {
675 $gmt_s = ! empty( $gmt ) ? 'G' : 'U';
676 $date = get_post_time( $gmt_s, $gmt, $reply_id );
677 $time = false; // For filter below
678 $result = bbp_get_time_since( $date );
679
680 // August 4, 2012 at 2:37 pm
681 } else {
682 $date = get_post_time( get_option( 'date_format' ), $gmt, $reply_id, true );
683 $time = get_post_time( get_option( 'time_format' ), $gmt, $reply_id, true );
684 $result = sprintf( _x( '%1$s at %2$s', 'date at time', 'bbpress' ), $date, $time );
685 }
686
687 // Filter & return
688 return apply_filters( 'bbp_get_reply_post_date', $result, $reply_id, $humanize, $gmt, $date, $time );
689 }
690
691 /**
692 * Append revisions to the reply content
693 *
694 * @since 2.0.0 bbPress (r2782)
695 *
696 * @param string $content Optional. Content to which we need to append the revisions to
697 * @param int $reply_id Optional. Reply id
698 * @return string Content with the revisions appended
699 */
700 function bbp_reply_content_append_revisions( $content = '', $reply_id = 0 ) {
701
702 // Bail if in admin or feed
703 if ( is_admin() || is_feed() ) {
704 return $content;
705 }
706
707 // Validate the ID
708 $reply_id = bbp_get_reply_id( $reply_id );
709
710 // Filter & return
711 return apply_filters( 'bbp_reply_append_revisions', $content . bbp_get_reply_revision_log( $reply_id ), $content, $reply_id );
712 }
713
714 /**
715 * Output the revision log of the reply
716 *
717 * @since 2.0.0 bbPress (r2782)
718 *
719 * @param int $reply_id Optional. Reply id
720 */
721 function bbp_reply_revision_log( $reply_id = 0 ) {
722 echo bbp_get_reply_revision_log( $reply_id );
723 }
724 /**
725 * Return the formatted revision log of the reply
726 *
727 * @since 2.0.0 bbPress (r2782)
728 *
729 * @param int $reply_id Optional. Reply id
730 * @return string Revision log of the reply
731 */
732 function bbp_get_reply_revision_log( $reply_id = 0 ) {
733
734 // Create necessary variables
735 $reply_id = bbp_get_reply_id( $reply_id );
736
737 // Show the topic reply log if this is a topic in a reply loop
738 if ( bbp_is_topic( $reply_id ) ) {
739 return bbp_get_topic_revision_log( $reply_id );
740 }
741
742 // Get the reply revision log (out of post meta
743 $revision_log = bbp_get_reply_raw_revision_log( $reply_id );
744
745 // Check reply and revision log exist
746 if ( empty( $reply_id ) || empty( $revision_log ) || ! is_array( $revision_log ) ) {
747 return false;
748 }
749
750 // Get the actual revisions
751 $revisions = bbp_get_reply_revisions( $reply_id );
752 if ( empty( $revisions ) ) {
753 return false;
754 }
755
756 $r = "\n\n" . '<ul id="bbp-reply-revision-log-' . esc_attr( $reply_id ) . '" class="bbp-reply-revision-log">' . "\n\n";
757
758 // Loop through revisions
759 foreach ( (array) $revisions as $revision ) {
760
761 if ( empty( $revision_log[ $revision->ID ] ) ) {
762 $author_id = $revision->post_author;
763 $reason = '';
764 } else {
765 $author_id = $revision_log[ $revision->ID ]['author'];
766 $reason = $revision_log[ $revision->ID ]['reason'];
767 }
768
769 $author = bbp_get_author_link( array( 'size' => 14, 'link_text' => bbp_get_reply_author_display_name( $revision->ID ), 'post_id' => $revision->ID ) );
770 $since = bbp_get_time_since( bbp_convert_date( $revision->post_modified ) );
771
772 $r .= "\t" . '<li id="bbp-reply-revision-log-' . esc_attr( $reply_id ) . '-item-' . esc_attr( $revision->ID ) . '" class="bbp-reply-revision-log-item">' . "\n";
773 if ( ! empty( $reason ) ) {
774 $r .= "\t\t" . sprintf( esc_html__( 'This reply was modified %1$s by %2$s. Reason: %3$s', 'bbpress' ), esc_html( $since ), $author, esc_html( $reason ) ) . "\n";
775 } else {
776 $r .= "\t\t" . sprintf( esc_html__( 'This reply was modified %1$s by %2$s.', 'bbpress' ), esc_html( $since ), $author ) . "\n";
777 }
778 $r .= "\t" . '</li>' . "\n";
779
780 }
781
782 $r .= "\n" . '</ul>' . "\n\n";
783
784 // Filter & return
785 return apply_filters( 'bbp_get_reply_revision_log', $r, $reply_id );
786 }
787 /**
788 * Return the raw revision log of the reply
789 *
790 * @since 2.0.0 bbPress (r2782)
791 *
792 * @param int $reply_id Optional. Reply id
793 * @return string Raw revision log of the reply
794 */
795 function bbp_get_reply_raw_revision_log( $reply_id = 0 ) {
796 $reply_id = bbp_get_reply_id( $reply_id );
797 $revision_log = get_post_meta( $reply_id, '_bbp_revision_log', true );
798 $revision_log = ! empty( $revision_log )
799 ? $revision_log
800 : array();
801
802 // Filter & return
803 return apply_filters( 'bbp_get_reply_raw_revision_log', $revision_log, $reply_id );
804 }
805
806 /**
807 * Return the revisions of the reply
808 *
809 * @since 2.0.0 bbPress (r2782)
810 *
811 * @param int $reply_id Optional. Reply id
812 * @return WP_Post[]|int[] reply revisions
813 */
814 function bbp_get_reply_revisions( $reply_id = 0 ) {
815 $reply_id = bbp_get_reply_id( $reply_id );
816 $revisions = wp_get_post_revisions( $reply_id, array( 'order' => 'ASC' ) );
817
818 // Filter & return
819 return apply_filters( 'bbp_get_reply_revisions', $revisions, $reply_id );
820 }
821
822 /**
823 * Return the revision count of the reply
824 *
825 * @since 2.0.0 bbPress (r2782)
826 *
827 * @param int $reply_id Optional. Reply id
828 * @param boolean $integer Optional. Whether or not to format the result
829 * @return string reply revision count
830 */
831 function bbp_get_reply_revision_count( $reply_id = 0, $integer = false ) {
832 $reply_id = bbp_get_reply_id( $reply_id );
833 $count = count( bbp_get_reply_revisions( $reply_id ) );
834 $filter = ( true === $integer )
835 ? 'bbp_get_reply_revision_count_int'
836 : 'bbp_get_reply_revision_count';
837
838 return apply_filters( $filter, $count, $reply_id );
839 }
840
841 /**
842 * Output the status of the reply
843 *
844 * @since 2.0.0 bbPress (r2667)
845 *
846 * @param int $reply_id Optional. Reply id
847 */
848 function bbp_reply_status( $reply_id = 0 ) {
849 echo bbp_get_reply_status( $reply_id );
850 }
851 /**
852 * Return the status of the reply
853 *
854 * @since 2.0.0 bbPress (r2667)
855 *
856 * @param int $reply_id Optional. Reply id
857 * @return string Status of reply
858 */
859 function bbp_get_reply_status( $reply_id = 0 ) {
860 $reply_id = bbp_get_reply_id( $reply_id );
861
862 // Filter & return
863 return apply_filters( 'bbp_get_reply_status', get_post_status( $reply_id ), $reply_id );
864 }
865
866 /**
867 * Is the reply publicly viewable?
868 *
869 * See bbp_get_public_reply_statuses() for public statuses.
870 *
871 * @since 2.6.0 bbPress (r6391)
872 *
873 * @param int $reply_id Optional. Reply id
874 * @return bool True if public, false if not.
875 */
876 function bbp_is_reply_public( $reply_id = 0 ) {
877 $reply_id = bbp_get_reply_id( $reply_id );
878 $status = bbp_get_reply_status( $reply_id );
879 $public = bbp_get_public_reply_statuses();
880 $is_public = in_array( $status, $public, true );
881
882 // Filter & return
883 return (bool) apply_filters( 'bbp_is_reply_public', $is_public, $reply_id );
884 }
885
886 /**
887 * Is the reply not spam or deleted?
888 *
889 * @since 2.0.0 bbPress (r3496)
890 * @since 2.6.0 bbPress (r6922) Returns false if topic is also not published
891 *
892 * @param int $reply_id Optional. Topic id
893 * @return bool True if published, false if not.
894 */
895 function bbp_is_reply_published( $reply_id = 0 ) {
896 $reply_id = bbp_get_reply_id( $reply_id );
897 $topic_id = bbp_get_reply_topic_id( $reply_id );
898 $status = bbp_get_public_status_id();
899 $topic_status = bbp_is_topic_published( $topic_id );
900 $reply_status = ( bbp_get_reply_status( $reply_id ) === $status );
901 $retval = ( $reply_status && $topic_status );
902
903 // Filter & return
904 return (bool) apply_filters( 'bbp_is_reply_published', (bool) $retval, $reply_id );
905 }
906
907 /**
908 * Is the reply marked as spam?
909 *
910 * @since 2.0.0 bbPress (r2740)
911 *
912 * @param int $reply_id Optional. Reply id
913 * @return bool True if spam, false if not.
914 */
915 function bbp_is_reply_spam( $reply_id = 0 ) {
916 $reply_id = bbp_get_reply_id( $reply_id );
917 $status = bbp_get_spam_status_id();
918 $reply_status = bbp_get_reply_status( $reply_id ) === $status;
919
920 // Filter & return
921 return (bool) apply_filters( 'bbp_is_reply_spam', (bool) $reply_status, $reply_id );
922 }
923
924 /**
925 * Is the reply trashed?
926 *
927 * @since 2.0.0 bbPress (r2884)
928 *
929 * @param int $reply_id Optional. Topic id
930 * @return bool True if spam, false if not.
931 */
932 function bbp_is_reply_trash( $reply_id = 0 ) {
933 $reply_id = bbp_get_reply_id( $reply_id );
934 $status = bbp_get_trash_status_id();
935 $reply_status = bbp_get_reply_status( $reply_id ) === $status;
936
937 // Filter & return
938 return (bool) apply_filters( 'bbp_is_reply_trash', (bool) $reply_status, $reply_id );
939 }
940
941 /**
942 * Is the reply pending?
943 *
944 * @since 2.6.0 bbPress (r5507)
945 *
946 * @param int $reply_id Optional. Topic id
947 * @return bool True if pending, false if not.
948 */
949 function bbp_is_reply_pending( $reply_id = 0 ) {
950 $reply_id = bbp_get_reply_id( $reply_id );
951 $status = bbp_get_pending_status_id();
952 $reply_status = bbp_get_reply_status( $reply_id ) === $status;
953
954 // Filter & return
955 return (bool) apply_filters( 'bbp_is_reply_pending', (bool) $reply_status, $reply_id );
956 }
957
958 /**
959 * Is the reply private?
960 *
961 * @since 2.6.0 bbPress (r5507)
962 *
963 * @param int $reply_id Optional. Topic id
964 * @return bool True if private, false if not.
965 */
966 function bbp_is_reply_private( $reply_id = 0 ) {
967 $reply_id = bbp_get_reply_id( $reply_id );
968 $status = bbp_get_private_status_id();
969 $reply_status = bbp_get_reply_status( $reply_id ) === $status;
970
971 // Filter & return
972 return (bool) apply_filters( 'bbp_is_reply_private', (bool) $reply_status, $reply_id );
973 }
974
975 /**
976 * Is the reply by an anonymous user?
977 *
978 * @since 2.0.0 bbPress (r2753)
979 *
980 * @param int $reply_id Optional. Reply id
981 * @return bool True if the post is by an anonymous user, false if not.
982 */
983 function bbp_is_reply_anonymous( $reply_id = 0 ) {
984 $reply_id = bbp_get_reply_id( $reply_id );
985 $retval = false;
986
987 if ( ! bbp_get_reply_author_id( $reply_id ) ) {
988 $retval = true;
989
990 } elseif ( get_post_meta( $reply_id, '_bbp_anonymous_name', true ) ) {
991 $retval = true;
992
993 } elseif ( get_post_meta( $reply_id, '_bbp_anonymous_email', true ) ) {
994 $retval = true;
995 }
996
997 // Filter & return
998 return (bool) apply_filters( 'bbp_is_reply_anonymous', $retval, $reply_id );
999 }
1000
1001 /**
1002 * Deprecated. Use bbp_reply_author_display_name() instead.
1003 *
1004 * Output the author of the reply
1005 *
1006 * @since 2.0.0 bbPress (r2667)
1007 *
1008 * @deprecated 2.5.0 bbPress (r5119)
1009 *
1010 * @param int $reply_id Optional. Reply id
1011 */
1012 function bbp_reply_author( $reply_id = 0 ) {
1013 echo bbp_get_reply_author( $reply_id );
1014 }
1015 /**
1016 * Deprecated. Use bbp_get_reply_author_display_name() instead.
1017 *
1018 * Return the author of the reply
1019 *
1020 * @since 2.0.0 bbPress (r2667)
1021 *
1022 * @deprecated 2.5.0 bbPress (r5119)
1023 *
1024 * @param int $reply_id Optional. Reply id
1025 * @return string Author of reply
1026 */
1027 function bbp_get_reply_author( $reply_id = 0 ) {
1028 $reply_id = bbp_get_reply_id( $reply_id );
1029
1030 if ( ! bbp_is_reply_anonymous( $reply_id ) ) {
1031 $author = get_the_author_meta( 'display_name', bbp_get_reply_author_id( $reply_id ) );
1032 } else {
1033 $author = get_post_meta( $reply_id, '_bbp_anonymous_name', true );
1034 }
1035
1036 // Filter & return
1037 return apply_filters( 'bbp_get_reply_author', $author, $reply_id );
1038 }
1039
1040 /**
1041 * Output the author ID of the reply
1042 *
1043 * @since 2.0.0 bbPress (r2667)
1044 *
1045 * @param int $reply_id Optional. Reply id
1046 */
1047 function bbp_reply_author_id( $reply_id = 0 ) {
1048 echo bbp_get_reply_author_id( $reply_id );
1049 }
1050 /**
1051 * Return the author ID of the reply
1052 *
1053 * @since 2.0.0 bbPress (r2667)
1054 *
1055 * @param int $reply_id Optional. Reply id
1056 * @return string Author id of reply
1057 */
1058 function bbp_get_reply_author_id( $reply_id = 0 ) {
1059 $reply_id = bbp_get_reply_id( $reply_id );
1060 $author_id = get_post_field( 'post_author', $reply_id );
1061
1062 // Filter & return
1063 return (int) apply_filters( 'bbp_get_reply_author_id', $author_id, $reply_id );
1064 }
1065
1066 /**
1067 * Output the author display_name of the reply
1068 *
1069 * @since 2.0.0 bbPress (r2667)
1070 *
1071 * @param int $reply_id Optional. Reply id
1072 */
1073 function bbp_reply_author_display_name( $reply_id = 0 ) {
1074 echo bbp_get_reply_author_display_name( $reply_id );
1075 }
1076 /**
1077 * Return the author display_name of the reply
1078 *
1079 * @since 2.0.0 bbPress (r2667)
1080 *
1081 * @param int $reply_id Optional. Reply id
1082 * @return string The display name of the author of the reply
1083 */
1084 function bbp_get_reply_author_display_name( $reply_id = 0 ) {
1085 $reply_id = bbp_get_reply_id( $reply_id );
1086
1087 // User is not a guest
1088 if ( ! bbp_is_reply_anonymous( $reply_id ) ) {
1089
1090 // Get the author ID
1091 $author_id = bbp_get_reply_author_id( $reply_id );
1092
1093 // Try to get a display name
1094 $author_name = get_the_author_meta( 'display_name', $author_id );
1095
1096 // Fall back to user login
1097 if ( empty( $author_name ) ) {
1098 $author_name = get_the_author_meta( 'user_login', $author_id );
1099 }
1100
1101 // User does not have an account
1102 } else {
1103 $author_name = get_post_meta( $reply_id, '_bbp_anonymous_name', true );
1104 }
1105
1106 // Fallback if nothing could be found
1107 if ( empty( $author_name ) ) {
1108 $author_name = bbp_get_fallback_display_name( $reply_id );
1109 }
1110
1111 // Filter & return
1112 return apply_filters( 'bbp_get_reply_author_display_name', $author_name, $reply_id );
1113 }
1114
1115 /**
1116 * Output the author avatar of the reply
1117 *
1118 * @since 2.0.0 bbPress (r2667)
1119 *
1120 * @param int $reply_id Optional. Reply id
1121 * @param int $size Optional. Size of the avatar. Defaults to 40
1122 */
1123 function bbp_reply_author_avatar( $reply_id = 0, $size = 40 ) {
1124 echo bbp_get_reply_author_avatar( $reply_id, $size );
1125 }
1126 /**
1127 * Return the author avatar of the reply
1128 *
1129 * @since 2.0.0 bbPress (r2667)
1130 *
1131 * @param int $reply_id Optional. Reply id
1132 * @param int $size Optional. Size of the avatar. Defaults to 40
1133 * @return string Avatar of author of the reply
1134 */
1135 function bbp_get_reply_author_avatar( $reply_id = 0, $size = 40 ) {
1136 $reply_id = bbp_get_reply_id( $reply_id );
1137 if ( ! empty( $reply_id ) ) {
1138 // Check for anonymous user
1139 if ( ! bbp_is_reply_anonymous( $reply_id ) ) {
1140 $author_avatar = get_avatar( bbp_get_reply_author_id( $reply_id ), $size );
1141 } else {
1142 $author_avatar = get_avatar( get_post_meta( $reply_id, '_bbp_anonymous_email', true ), $size );
1143 }
1144 } else {
1145 $author_avatar = '';
1146 }
1147
1148 // Filter & return
1149 return apply_filters( 'bbp_get_reply_author_avatar', $author_avatar, $reply_id, $size );
1150 }
1151
1152 /**
1153 * Output the author link of the reply
1154 *
1155 * @since 2.0.0 bbPress (r2717)
1156 *
1157 * @param array $args Optional. If it is an integer, it is used as reply id.
1158 */
1159 function bbp_reply_author_link( $args = array() ) {
1160 echo bbp_get_reply_author_link( $args );
1161 }
1162 /**
1163 * Return the author link of the reply
1164 *
1165 * @since 2.0.0 bbPress (r2717)
1166 *
1167 * @param array $args Optional. If an integer, it is used as reply id.
1168 * @return string Author link of reply
1169 */
1170 function bbp_get_reply_author_link( $args = array() ) {
1171
1172 // Parse arguments against default values
1173 $r = bbp_parse_args( $args, array(
1174 'post_id' => 0,
1175 'link_title' => '',
1176 'type' => 'both',
1177 'size' => 80,
1178 'sep' => '',
1179 'show_role' => false
1180 ), 'get_reply_author_link' );
1181
1182 // Default return value
1183 $author_link = '';
1184
1185 // Used as reply_id
1186 $reply_id = is_numeric( $args )
1187 ? bbp_get_reply_id( $args )
1188 : bbp_get_reply_id( $r['post_id'] );
1189
1190 // Reply ID is good
1191 if ( ! empty( $reply_id ) ) {
1192
1193 // Get some useful reply information
1194 $author_url = bbp_get_reply_author_url( $reply_id );
1195 $anonymous = bbp_is_reply_anonymous( $reply_id );
1196
1197 // Tweak link title if empty
1198 if ( empty( $r['link_title'] ) ) {
1199 $author = bbp_get_reply_author_display_name( $reply_id );
1200 $title = empty( $anonymous )
1201 ? esc_attr__( "View %s's profile", 'bbpress' )
1202 : esc_attr__( "Visit %s's website", 'bbpress' );
1203
1204 $link_title = sprintf( $title, $author );
1205
1206 // Use what was passed if not
1207 } else {
1208 $link_title = $r['link_title'];
1209 }
1210
1211 // Setup title and author_links array
1212 $author_links = array();
1213 $link_title = ! empty( $link_title )
1214 ? ' title="' . esc_attr( $link_title ) . '"'
1215 : '';
1216
1217 // Get avatar (unescaped, because HTML)
1218 if ( ( 'avatar' === $r['type'] ) || ( 'both' === $r['type'] ) ) {
1219 $author_links['avatar'] = bbp_get_reply_author_avatar( $reply_id, $r['size'] );
1220 }
1221
1222 // Get display name (escaped, because never HTML)
1223 if ( ( 'name' === $r['type'] ) || ( 'both' === $r['type'] ) ) {
1224 $author_links['name'] = esc_html( bbp_get_reply_author_display_name( $reply_id ) );
1225 }
1226
1227 // Empty array
1228 $links = array();
1229 $sprint = '<span %1$s>%2$s</span>';
1230
1231 // Wrap each link
1232 foreach ( $author_links as $link => $link_text ) {
1233 $link_class = ' class="bbp-author-' . esc_attr( $link ) . '"';
1234 $links[] = sprintf( $sprint, $link_class, $link_text );
1235 }
1236
1237 // Juggle
1238 $author_links = $links;
1239 unset( $links );
1240
1241 // Filter sections
1242 $sections = apply_filters( 'bbp_get_reply_author_links', $author_links, $r, $args );
1243
1244 // Assemble sections into author link
1245 $author_link = implode( $r['sep'], $sections );
1246
1247 // Only wrap in link if profile exists
1248 if ( empty( $anonymous ) && bbp_user_has_profile( bbp_get_reply_author_id( $reply_id ) ) ) {
1249 $author_link = sprintf( '<a href="%1$s"%2$s%3$s>%4$s</a>', esc_url( $author_url ), $link_title, ' class="bbp-author-link"', $author_link );
1250 }
1251
1252 // Role is not linked
1253 if ( true === $r['show_role'] ) {
1254 $author_link .= bbp_get_reply_author_role( array( 'reply_id' => $reply_id ) );
1255 }
1256 }
1257
1258 // Filter & return
1259 return apply_filters( 'bbp_get_reply_author_link', $author_link, $r, $args );
1260 }
1261
1262 /**
1263 * Output the author url of the reply
1264 *
1265 * @since 2.0.0 bbPress (r2667)
1266 *
1267 * @param int $reply_id Optional. Reply id
1268 */
1269 function bbp_reply_author_url( $reply_id = 0 ) {
1270 echo esc_url( bbp_get_reply_author_url( $reply_id ) );
1271 }
1272 /**
1273 * Return the author url of the reply
1274 *
1275 * @since 2.0.0 bbPress (r2667)
1276 *
1277 * @param int $reply_id Optional. Reply id
1278 * @return string Author URL of the reply
1279 */
1280 function bbp_get_reply_author_url( $reply_id = 0 ) {
1281 $reply_id = bbp_get_reply_id( $reply_id );
1282
1283 // Check for anonymous user or non-existant user
1284 if ( ! bbp_is_reply_anonymous( $reply_id ) && bbp_user_has_profile( bbp_get_reply_author_id( $reply_id ) ) ) {
1285 $author_url = bbp_get_user_profile_url( bbp_get_reply_author_id( $reply_id ) );
1286 } else {
1287 $author_url = get_post_meta( $reply_id, '_bbp_anonymous_website', true );
1288 if ( empty( $author_url ) ) {
1289 $author_url = '';
1290 }
1291 }
1292
1293 // Filter & return
1294 return apply_filters( 'bbp_get_reply_author_url', $author_url, $reply_id );
1295 }
1296
1297 /**
1298 * Output the reply author email address
1299 *
1300 * @since 2.0.0 bbPress (r3445)
1301 *
1302 * @param int $reply_id Optional. Reply id
1303 */
1304 function bbp_reply_author_email( $reply_id = 0 ) {
1305 echo bbp_get_reply_author_email( $reply_id );
1306 }
1307 /**
1308 * Return the reply author email address
1309 *
1310 * @since 2.0.0 bbPress (r3445)
1311 *
1312 * @param int $reply_id Optional. Reply id
1313 * @return string Reply author email address
1314 */
1315 function bbp_get_reply_author_email( $reply_id = 0 ) {
1316 $reply_id = bbp_get_reply_id( $reply_id );
1317
1318 // Not anonymous
1319 if ( ! bbp_is_reply_anonymous( $reply_id ) ) {
1320
1321 // Use reply author email address
1322 $user_id = bbp_get_reply_author_id( $reply_id );
1323 $user = get_userdata( $user_id );
1324 $author_email = ! empty( $user->user_email ) ? $user->user_email : '';
1325
1326 // Anonymous
1327 } else {
1328
1329 // Get email from post meta
1330 $author_email = get_post_meta( $reply_id, '_bbp_anonymous_email', true );
1331
1332 // Sanity check for missing email address
1333 if ( empty( $author_email ) ) {
1334 $author_email = '';
1335 }
1336 }
1337
1338 // Filter & return
1339 return apply_filters( 'bbp_get_reply_author_email', $author_email, $reply_id );
1340 }
1341
1342 /**
1343 * Output the reply author role
1344 *
1345 * @since 2.1.0 bbPress (r3860)
1346 *
1347 * @param array $args Optional.
1348 */
1349 function bbp_reply_author_role( $args = array() ) {
1350 echo bbp_get_reply_author_role( $args );
1351 }
1352 /**
1353 * Return the reply author role
1354 *
1355 * @since 2.1.0 bbPress (r3860)
1356 *
1357 * @param array $args Optional.
1358 * @return string Reply author role
1359 */
1360 function bbp_get_reply_author_role( $args = array() ) {
1361
1362 // Parse arguments against default values
1363 $r = bbp_parse_args( $args, array(
1364 'reply_id' => 0,
1365 'class' => false,
1366 'before' => '<div class="bbp-author-role">',
1367 'after' => '</div>'
1368 ), 'get_reply_author_role' );
1369
1370 $reply_id = bbp_get_reply_id( $r['reply_id'] );
1371 $role = bbp_get_user_display_role( bbp_get_reply_author_id( $reply_id ) );
1372
1373 // Backwards compatibilty with old 'class' argument
1374 if ( ! empty( $r['class'] ) ) {
1375 $author_role = sprintf( '%1$s<div class="%2$s">%3$s</div>%4$s', $r['before'], esc_attr( $r['class'] ), esc_html( $role ), $r['after'] );
1376
1377 // Simpler before & after arguments
1378 // https://bbpress.trac.wordpress.org/ticket/2557
1379 } else {
1380 $author_role = $r['before'] . $role . $r['after'];
1381 }
1382
1383 // Filter & return
1384 return apply_filters( 'bbp_get_reply_author_role', $author_role, $r, $args );
1385 }
1386
1387 /**
1388 * Output the topic title a reply belongs to
1389 *
1390 * @since 2.0.0 bbPress (r2553)
1391 *
1392 * @param int $reply_id Optional. Reply id
1393 */
1394 function bbp_reply_topic_title( $reply_id = 0 ) {
1395 echo bbp_get_reply_topic_title( $reply_id );
1396 }
1397 /**
1398 * Return the topic title a reply belongs to
1399 *
1400 * @since 2.0.0 bbPress (r2553)
1401 *
1402 * @param int $reply_id Optional. Reply id
1403 * @return string The topic title of the reply
1404 */
1405 function bbp_get_reply_topic_title( $reply_id = 0 ) {
1406 $reply_id = bbp_get_reply_id( $reply_id );
1407 $topic_id = bbp_get_reply_topic_id( $reply_id );
1408
1409 // Filter & return
1410 return apply_filters( 'bbp_get_reply_topic_title', bbp_get_topic_title( $topic_id ), $reply_id );
1411 }
1412
1413 /**
1414 * Output the topic id a reply belongs to
1415 *
1416 * @since 2.0.0 bbPress (r2553)
1417 *
1418 * @param int $reply_id Optional. Reply id
1419 */
1420 function bbp_reply_topic_id( $reply_id = 0 ) {
1421 echo bbp_get_reply_topic_id( $reply_id );
1422 }
1423 /**
1424 * Return the topic id a reply belongs to
1425 *
1426 * @since 2.0.0 bbPress (r2553)
1427 *
1428 * @param int $reply_id Optional. Reply id
1429 * @return int The topic id of the reply
1430 */
1431 function bbp_get_reply_topic_id( $reply_id = 0 ) {
1432 $reply_id = bbp_get_reply_id( $reply_id );
1433 $topic_id = (int) get_post_field( 'post_parent', $reply_id );
1434
1435 // Meta-data fallback
1436 if ( empty( $topic_id ) ) {
1437 $topic_id = (int) get_post_meta( $reply_id, '_bbp_topic_id', true );
1438 }
1439
1440 // Filter
1441 if ( ! empty( $topic_id ) ) {
1442 $topic_id = (int) bbp_get_topic_id( $topic_id );
1443 }
1444
1445 // Filter & return
1446 return (int) apply_filters( 'bbp_get_reply_topic_id', $topic_id, $reply_id );
1447 }
1448
1449 /**
1450 * Output the forum id a reply belongs to
1451 *
1452 * @since 2.0.0 bbPress (r2679)
1453 *
1454 * @param int $reply_id Optional. Reply id
1455 */
1456 function bbp_reply_forum_id( $reply_id = 0 ) {
1457 echo bbp_get_reply_forum_id( $reply_id );
1458 }
1459 /**
1460 * Return the forum id a reply belongs to
1461 *
1462 * @since 2.0.0 bbPress (r2679)
1463 *
1464 * @param int $reply_id Optional. Reply id
1465 *
1466 * @return int The forum id of the reply
1467 */
1468 function bbp_get_reply_forum_id( $reply_id = 0 ) {
1469 $reply_id = bbp_get_reply_id( $reply_id );
1470 $topic_id = bbp_get_reply_topic_id( $reply_id );
1471 $forum_id = (int) get_post_field( 'post_parent', $topic_id );
1472
1473 // Meta-data fallback
1474 if ( empty( $forum_id ) ) {
1475 $forum_id = (int) get_post_meta( $reply_id, '_bbp_forum_id', true );
1476 }
1477
1478 // Filter
1479 if ( ! empty( $forum_id ) ) {
1480 $forum_id = (int) bbp_get_forum_id( $forum_id );
1481 }
1482
1483 // Filter & return
1484 return (int) apply_filters( 'bbp_get_reply_forum_id', $forum_id, $reply_id );
1485 }
1486
1487 /**
1488 * Output the ancestor reply id of a reply
1489 *
1490 * @since 2.4.0 bbPress (r4944)
1491 *
1492 * @param int $reply_id Optional. Reply id
1493 */
1494 function bbp_reply_ancestor_id( $reply_id = 0 ) {
1495 echo bbp_get_reply_ancestor_id( $reply_id );
1496 }
1497 /**
1498 * Return the ancestor reply id of a reply
1499 *
1500 * @since 2.4.0 bbPress (r4944)
1501 *
1502 * @param in $reply_id Reply id
1503 */
1504 function bbp_get_reply_ancestor_id( $reply_id = 0 ) {
1505
1506 // Validation
1507 $reply_id = bbp_get_reply_id( $reply_id );
1508 if ( empty( $reply_id ) ) {
1509 return false;
1510 }
1511
1512 // Find highest reply ancestor
1513 $ancestor_id = $reply_id;
1514 while ( $parent_id = bbp_get_reply_to( $ancestor_id ) ) {
1515 if ( empty( $parent_id ) || ( $parent_id === $ancestor_id ) || ( bbp_get_reply_topic_id( $reply_id ) === $parent_id ) || ( $parent_id === $reply_id ) ) {
1516 break;
1517 }
1518 $ancestor_id = $parent_id;
1519 }
1520
1521 return (int) $ancestor_id;
1522 }
1523
1524 /**
1525 * Output the reply to id of a reply
1526 *
1527 * @since 2.4.0 bbPress (r4944)
1528 *
1529 * @param int $reply_id Optional. Reply id
1530 */
1531 function bbp_reply_to( $reply_id = 0 ) {
1532 echo bbp_get_reply_to( $reply_id );
1533 }
1534 /**
1535 * Return the reply to id of a reply
1536 *
1537 * @since 2.4.0 bbPress (r4944)
1538 *
1539 * @param int $reply_id Optional. Reply id
1540 * @return int The parent reply id of the reply
1541 */
1542 function bbp_get_reply_to( $reply_id = 0 ) {
1543
1544 // Assume there is no reply_to set
1545 $reply_to = 0;
1546
1547 // Check that reply_id is valid
1548 $reply_id = bbp_get_reply_id( $reply_id );
1549
1550 // Get reply_to value
1551 if ( ! empty( $reply_id ) ) {
1552 $reply_to = (int) get_post_meta( $reply_id, '_bbp_reply_to', true );
1553 }
1554
1555 // Filter & return
1556 return (int) apply_filters( 'bbp_get_reply_to', $reply_to, $reply_id );
1557 }
1558
1559 /**
1560 * Output the link for the reply to
1561 *
1562 * @since 2.4.0 bbPress (r4944)
1563 *
1564 * @param array $args
1565 */
1566 function bbp_reply_to_link( $args = array() ) {
1567 echo bbp_get_reply_to_link( $args );
1568 }
1569
1570 /**
1571 * Return the link for a reply to a reply
1572 *
1573 * @since 2.4.0 bbPress (r4944)
1574 *
1575 * @param array $args Arguments
1576 * @return string Link for a reply to a reply
1577 */
1578 function bbp_get_reply_to_link( $args = array() ) {
1579
1580 // Parse arguments against default values
1581 $r = bbp_parse_args( $args, array(
1582 'id' => 0,
1583 'link_before' => '',
1584 'link_after' => '',
1585 'reply_text' => esc_html_x( 'Reply', 'verb', 'bbpress' ),
1586 'depth' => 0,
1587 'add_below' => 'post',
1588 'respond_id' => 'new-reply-' . bbp_get_topic_id(),
1589 ), 'get_reply_to_link' );
1590
1591 // Get the reply to use it's ID and post_parent
1592 $reply = bbp_get_reply( $r['id'] );
1593 $topic_id = bbp_get_reply_topic_id( $reply->ID );
1594
1595 // Bail if no reply or user cannot reply
1596 if ( empty( $reply ) || empty( $topic_id ) || bbp_is_single_reply() || ! bbp_current_user_can_access_create_reply_form() ) {
1597 return;
1598 }
1599
1600 // Build the URI and return value
1601 $uri = bbp_get_reply_url( $reply->ID );
1602 $uri = strtok( $uri, "#" );
1603 $uri = add_query_arg( array( 'bbp_reply_to' => $reply->ID ), $uri );
1604 $uri = wp_nonce_url( $uri, 'respond_id_' . $reply->ID );
1605 $uri = $uri . '#new-post';
1606
1607 // Only add onclick if replies are threaded
1608 if ( bbp_thread_replies() ) {
1609
1610 // Array of classes to pass to moveForm
1611 $move_form = array(
1612 $r['add_below'] . '-' . $reply->ID,
1613 $reply->ID,
1614 $r['respond_id'],
1615 $reply->post_parent
1616 );
1617
1618 // Build the onclick
1619 $onclick = ' onclick="return addReply.moveForm(\'' . implode( "','", $move_form ) . '\');"';
1620
1621 // No onclick if replies are not threaded
1622 } else {
1623 $onclick = '';
1624 }
1625
1626 // Add $uri to the array, to be passed through the filter
1627 $r['uri'] = $uri;
1628 $retval = $r['link_before'] . '<a role="button" href="' . esc_url( $r['uri'] ) . '" class="bbp-reply-to-link"' . $onclick . '>' . $r['reply_text'] . '</a>' . $r['link_after'];
1629
1630 // Filter & return
1631 return apply_filters( 'bbp_get_reply_to_link', $retval, $r, $args );
1632 }
1633
1634 /**
1635 * Output the reply to a reply cancellation link
1636 *
1637 * @since 2.4.0 bbPress (r4944)
1638 */
1639 function bbp_cancel_reply_to_link( $text = '' ) {
1640 echo bbp_get_cancel_reply_to_link( $text );
1641 }
1642 /**
1643 * Return the cancellation link for a reply to a reply
1644 *
1645 * @since 2.4.0 bbPress (r4944)
1646 *
1647 * @param string $text The cancel text
1648 * @return string The cancellation link
1649 */
1650 function bbp_get_cancel_reply_to_link( $text = '' ) {
1651
1652 // Bail if not hierarchical or editing a reply
1653 if ( ! bbp_thread_replies() || bbp_is_reply_edit() ) {
1654 return;
1655 }
1656
1657 // Set default text
1658 if ( empty( $text ) ) {
1659 $text = esc_html__( 'Cancel', 'bbpress' );
1660 }
1661
1662 // Replying to...
1663 $reply_to = isset( $_GET['bbp_reply_to'] )
1664 ? (int) $_GET['bbp_reply_to']
1665 : 0;
1666
1667 // Set visibility
1668 $style = ! empty( $reply_to ) ? '' : ' style="display:none;"';
1669 $link = remove_query_arg( array( 'bbp_reply_to', '_wpnonce' ) ) . "#post-{$reply_to}";
1670 $retval = sprintf( '<a href="%1$s" id="bbp-cancel-reply-to-link"%2$s>%3$s</a>', esc_url( $link ), $style, esc_html( $text ) );
1671
1672 // Filter & return
1673 return apply_filters( 'bbp_get_cancel_reply_to_link', $retval, $link, $text );
1674 }
1675
1676 /**
1677 * Output the numeric position of a reply within a topic
1678 *
1679 * @since 2.0.0 bbPress (r2984)
1680 *
1681 * @param int $reply_id Optional. Reply id
1682 * @param int $topic_id Optional. Topic id
1683 */
1684 function bbp_reply_position( $reply_id = 0, $topic_id = 0 ) {
1685 echo bbp_get_reply_position( $reply_id, $topic_id );
1686 }
1687 /**
1688 * Return the numeric position of a reply within a topic
1689 *
1690 * @since 2.0.0 bbPress (r2984)
1691 *
1692 * @param int $reply_id Optional. Reply id
1693 * @param int $topic_id Optional. Topic id
1694 * @return int Reply position
1695 */
1696 function bbp_get_reply_position( $reply_id = 0, $topic_id = 0 ) {
1697
1698 // Get required data
1699 $reply_id = bbp_get_reply_id( $reply_id );
1700 $reply_position = get_post_field( 'menu_order', $reply_id );
1701
1702 // Reply doesn't have a position so get the raw value
1703 if ( empty( $reply_position ) ) {
1704
1705 // Get topic ID
1706 $topic_id = ! empty( $topic_id )
1707 ? bbp_get_topic_id( $topic_id )
1708 : bbp_get_reply_topic_id( $reply_id );
1709
1710 // Post is not the topic
1711 if ( $reply_id !== $topic_id ) {
1712 $reply_position = bbp_get_reply_position_raw( $reply_id, $topic_id );
1713
1714 // Update the reply position in the posts table so we'll never have
1715 // to hit the DB again.
1716 if ( ! empty( $reply_position ) ) {
1717 bbp_update_reply_position( $reply_id, $reply_position );
1718 }
1719
1720 // Topic's position is always 0
1721 } else {
1722 $reply_position = 0;
1723 }
1724 }
1725
1726 // Bump the position by one if the topic is included in the reply loop
1727 if ( ! bbp_show_lead_topic() ) {
1728 $reply_position++;
1729 }
1730
1731 // Filter & return
1732 return (int) apply_filters( 'bbp_get_reply_position', $reply_position, $reply_id, $topic_id );
1733 }
1734
1735 /** Reply Admin Links *********************************************************/
1736
1737 /**
1738 * Output admin links for reply
1739 *
1740 * @since 2.0.0 bbPress (r2667)
1741 *
1742 * @param array $args See {@link bbp_get_reply_admin_links()}
1743 */
1744 function bbp_reply_admin_links( $args = array() ) {
1745 echo bbp_get_reply_admin_links( $args );
1746 }
1747 /**
1748 * Return admin links for reply
1749 *
1750 * @since 2.0.0 bbPress (r2667)
1751 *
1752 * @param array $args This function supports these arguments:
1753 * - id: Optional. Reply id
1754 * - before: HTML before the links. Defaults to
1755 * '<span class="bbp-admin-links">'
1756 * - after: HTML after the links. Defaults to '</span>'
1757 * - sep: Separator. Defaults to ' | '
1758 * - links: Array of the links to display. By default, edit, trash,
1759 * spam, reply move, and topic split links are displayed
1760 * @return string Reply admin links
1761 */
1762 function bbp_get_reply_admin_links( $args = array() ) {
1763
1764 // Parse arguments against default values
1765 $r = bbp_parse_args( $args, array(
1766 'id' => 0,
1767 'before' => '<span class="bbp-admin-links">',
1768 'after' => '</span>',
1769 'sep' => ' | ',
1770 'links' => array()
1771 ), 'get_reply_admin_links' );
1772
1773 $r['id'] = bbp_get_reply_id( $r['id'] );
1774
1775 // If post is a topic, return the topic admin links instead
1776 if ( bbp_is_topic( $r['id'] ) ) {
1777 return bbp_get_topic_admin_links( $args );
1778 }
1779
1780 // If post is not a reply, return
1781 if ( ! bbp_is_reply( $r['id'] ) ) {
1782 return;
1783 }
1784
1785 // If topic is trashed, do not show admin links
1786 if ( bbp_is_topic_trash( bbp_get_reply_topic_id( $r['id'] ) ) ) {
1787 return;
1788 }
1789
1790 // If no links were passed, default to the standard
1791 if ( empty( $r['links'] ) ) {
1792 $r['links'] = apply_filters( 'bbp_reply_admin_links', array(
1793 'edit' => bbp_get_reply_edit_link ( $r ),
1794 'move' => bbp_get_reply_move_link ( $r ),
1795 'split' => bbp_get_topic_split_link ( $r ),
1796 'trash' => bbp_get_reply_trash_link ( $r ),
1797 'spam' => bbp_get_reply_spam_link ( $r ),
1798 'approve' => bbp_get_reply_approve_link( $r ),
1799 'reply' => bbp_get_reply_to_link ( $r )
1800 ), $r['id'] );
1801 }
1802
1803 // See if links need to be unset
1804 $reply_status = bbp_get_reply_status( $r['id'] );
1805 if ( in_array( $reply_status, array( bbp_get_spam_status_id(), bbp_get_trash_status_id(), bbp_get_pending_status_id() ), true ) ) {
1806
1807 // Spam link shouldn't be visible on trashed topics
1808 if ( bbp_get_trash_status_id() === $reply_status ) {
1809 unset( $r['links']['spam'] );
1810
1811 // Trash link shouldn't be visible on spam topics
1812 } elseif ( bbp_get_spam_status_id() === $reply_status ) {
1813 unset( $r['links']['trash'] );
1814 }
1815 }
1816
1817 // Process the admin links
1818 $links = implode( $r['sep'], array_filter( $r['links'] ) );
1819 $retval = $r['before'] . $links . $r['after'];
1820
1821 // Filter & return
1822 return apply_filters( 'bbp_get_reply_admin_links', $retval, $r, $args );
1823 }
1824
1825 /**
1826 * Output the edit link of the reply
1827 *
1828 * @since 2.0.0 bbPress (r2740)
1829 *
1830 * @param array $args See {@link bbp_get_reply_edit_link()}
1831 */
1832 function bbp_reply_edit_link( $args = array() ) {
1833 echo bbp_get_reply_edit_link( $args );
1834 }
1835
1836 /**
1837 * Return the edit link of the reply
1838 *
1839 * @since 2.0.0 bbPress (r2740)
1840 *
1841 * @param array $args This function supports these arguments:
1842 * - id: Reply id
1843 * - link_before: HTML before the link
1844 * - link_after: HTML after the link
1845 * - edit_text: Edit text. Defaults to 'Edit'
1846 * @return string Reply edit link
1847 */
1848 function bbp_get_reply_edit_link( $args = array() ) {
1849
1850 // Parse arguments against default values
1851 $r = bbp_parse_args( $args, array(
1852 'id' => 0,
1853 'link_before' => '',
1854 'link_after' => '',
1855 'edit_text' => esc_html__( 'Edit', 'bbpress' )
1856 ), 'get_reply_edit_link' );
1857
1858 // Get reply
1859 $reply = bbp_get_reply( $r['id'] );
1860
1861 // Bypass check if user has caps
1862 if ( ! current_user_can( 'edit_others_replies' ) ) {
1863
1864 // User cannot edit or it is past the lock time
1865 if ( empty( $reply ) || ! current_user_can( 'edit_reply', $reply->ID ) || bbp_past_edit_lock( $reply->post_date_gmt ) ) {
1866 return;
1867 }
1868 }
1869
1870 // Get uri
1871 $uri = bbp_get_reply_edit_url( $r['id'] );
1872
1873 // Bail if no uri
1874 if ( empty( $uri ) ) {
1875 return;
1876 }
1877
1878 $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" class="bbp-reply-edit-link">' . $r['edit_text'] . '</a>' . $r['link_after'];
1879
1880 // Filter & return
1881 return apply_filters( 'bbp_get_reply_edit_link', $retval, $r, $args );
1882 }
1883
1884 /**
1885 * Output URL to the reply edit page
1886 *
1887 * @since 2.0.0 bbPress (r2753)
1888 *
1889 * @param int $reply_id Optional. Reply id
1890 */
1891 function bbp_reply_edit_url( $reply_id = 0 ) {
1892 echo esc_url( bbp_get_reply_edit_url( $reply_id ) );
1893 }
1894 /**
1895 * Return URL to the reply edit page
1896 *
1897 * @since 2.0.0 bbPress (r2753)
1898 *
1899 * @param int $reply_id Optional. Reply id
1900 * @return string Reply edit url
1901 */
1902 function bbp_get_reply_edit_url( $reply_id = 0 ) {
1903
1904 // Bail if no reply
1905 $reply = bbp_get_reply( $reply_id );
1906 if ( empty( $reply ) ) {
1907 return;
1908 }
1909
1910 $reply_link = bbp_remove_view_all( bbp_get_reply_permalink( $reply_id ) );
1911
1912 // Pretty permalinks, previously used `bbp_use_pretty_urls()`
1913 // https://bbpress.trac.wordpress.org/ticket/3054
1914 if ( false === strpos( $reply_link, '?' ) ) {
1915 $url = trailingslashit( $reply_link ) . bbp_get_edit_slug();
1916 $url = user_trailingslashit( $url );
1917
1918 // Unpretty permalinks
1919 } else {
1920 $url = add_query_arg( array(
1921 bbp_get_reply_post_type() => $reply->post_name,
1922 bbp_get_edit_rewrite_id() => '1'
1923 ), $reply_link );
1924 }
1925
1926 // Maybe add view all
1927 $url = bbp_add_view_all( $url );
1928
1929 // Filter & return
1930 return apply_filters( 'bbp_get_reply_edit_url', $url, $reply_id );
1931 }
1932
1933 /**
1934 * Output the trash link of the reply
1935 *
1936 * @since 2.0.0 bbPress (r2740)
1937 *
1938 * @param array $args See {@link bbp_get_reply_trash_link()}
1939 */
1940 function bbp_reply_trash_link( $args = array() ) {
1941 echo bbp_get_reply_trash_link( $args );
1942 }
1943
1944 /**
1945 * Return the trash link of the reply
1946 *
1947 * @since 2.0.0 bbPress (r2740)
1948 *
1949 * @param array $args This function supports these arguments:
1950 * - id: Reply id
1951 * - link_before: HTML before the link
1952 * - link_after: HTML after the link
1953 * - sep: Separator
1954 * - trash_text: Trash text
1955 * - restore_text: Restore text
1956 * - delete_text: Delete text
1957 * @return string Reply trash link
1958 */
1959 function bbp_get_reply_trash_link( $args = array() ) {
1960
1961 // Parse arguments against default values
1962 $r = bbp_parse_args( $args, array(
1963 'id' => 0,
1964 'link_before' => '',
1965 'link_after' => '',
1966 'sep' => ' | ',
1967 'trash_text' => esc_html__( 'Trash', 'bbpress' ),
1968 'restore_text' => esc_html__( 'Restore', 'bbpress' ),
1969 'delete_text' => esc_html__( 'Delete', 'bbpress' )
1970 ), 'get_reply_trash_link' );
1971
1972 // Get reply
1973 $reply = bbp_get_reply( $r['id'] );
1974
1975 // Bail if no reply or current user cannot delete
1976 if ( empty( $reply ) || ! current_user_can( 'delete_reply', $reply->ID ) ) {
1977 return;
1978 }
1979
1980 $actions = array();
1981 $trash_days = bbp_get_trash_days( bbp_get_reply_post_type() );
1982
1983 // Trashed
1984 if ( bbp_is_reply_trash( $reply->ID ) ) {
1985 $actions['untrash'] = '<a title="' . esc_attr__( 'Restore this item from the Trash', 'bbpress' ) . '" href="' . esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'bbp_toggle_reply_trash', 'sub_action' => 'untrash', 'reply_id' => $reply->ID ) ), 'untrash-' . $reply->post_type . '_' . $reply->ID ) ) . '" class="bbp-reply-restore-link">' . $r['restore_text'] . '</a>';
1986
1987 // Trash
1988 } elseif ( ! empty( $trash_days ) ) {
1989 $actions['trash'] = '<a title="' . esc_attr__( 'Move this item to the Trash', 'bbpress' ) . '" href="' . esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'bbp_toggle_reply_trash', 'sub_action' => 'trash', 'reply_id' => $reply->ID ) ), 'trash-' . $reply->post_type . '_' . $reply->ID ) ) . '" class="bbp-reply-trash-link">' . $r['trash_text'] . '</a>';
1990 }
1991
1992 // No trash
1993 if ( bbp_is_reply_trash( $reply->ID ) || empty( $trash_days ) ) {
1994 $actions['delete'] = '<a title="' . esc_attr__( 'Delete this item permanently', 'bbpress' ) . '" href="' . esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'bbp_toggle_reply_trash', 'sub_action' => 'delete', 'reply_id' => $reply->ID ) ), 'delete-' . $reply->post_type . '_' . $reply->ID ) ) . '" onclick="return confirm(\'' . esc_js( __( 'Are you sure you want to delete that permanently?', 'bbpress' ) ) . '\' );" class="bbp-reply-delete-link">' . $r['delete_text'] . '</a>';
1995 }
1996
1997 // Process the admin links
1998 $retval = $r['link_before'] . implode( $r['sep'], $actions ) . $r['link_after'];
1999
2000 // Filter & return
2001 return apply_filters( 'bbp_get_reply_trash_link', $retval, $r, $args );
2002 }
2003
2004 /**
2005 * Output the spam link of the reply
2006 *
2007 * @since 2.0.0 bbPress (r2740)
2008 *
2009 * @param array $args See {@link bbp_get_reply_spam_link()}
2010 */
2011 function bbp_reply_spam_link( $args = array() ) {
2012 echo bbp_get_reply_spam_link( $args );
2013 }
2014
2015 /**
2016 * Return the spam link of the reply
2017 *
2018 * @since 2.0.0 bbPress (r2740)
2019 *
2020 * @param array $args This function supports these arguments:
2021 * - id: Reply id
2022 * - link_before: HTML before the link
2023 * - link_after: HTML after the link
2024 * - spam_text: Spam text
2025 * - unspam_text: Unspam text
2026 * @return string Reply spam link
2027 */
2028 function bbp_get_reply_spam_link( $args = array() ) {
2029
2030 // Parse arguments against default values
2031 $r = bbp_parse_args( $args, array(
2032 'id' => 0,
2033 'link_before' => '',
2034 'link_after' => '',
2035 'spam_text' => esc_html__( 'Spam', 'bbpress' ),
2036 'unspam_text' => esc_html__( 'Unspam', 'bbpress' )
2037 ), 'get_reply_spam_link' );
2038
2039 // Get reply
2040 $reply = bbp_get_reply( $r['id'] );
2041
2042 // Bail if no reply or current user cannot moderate
2043 if ( empty( $reply ) || ! current_user_can( 'moderate', $reply->ID ) ) {
2044 return;
2045 }
2046
2047 $display = bbp_is_reply_spam( $reply->ID ) ? $r['unspam_text'] : $r['spam_text'];
2048 $uri = add_query_arg( array( 'action' => 'bbp_toggle_reply_spam', 'reply_id' => $reply->ID ) );
2049 $uri = wp_nonce_url( $uri, 'spam-reply_' . $reply->ID );
2050 $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" class="bbp-reply-spam-link">' . $display . '</a>' . $r['link_after'];
2051
2052 // Filter & return
2053 return apply_filters( 'bbp_get_reply_spam_link', $retval, $r, $args );
2054 }
2055
2056 /**
2057 * Move reply link
2058 *
2059 * Output the move link of the reply
2060 *
2061 * @since 2.3.0 bbPress (r4521)
2062 *
2063 * @param array $args See {@link bbp_get_reply_move_link()}
2064 */
2065 function bbp_reply_move_link( $args = array() ) {
2066 echo bbp_get_reply_move_link( $args );
2067 }
2068
2069 /**
2070 * Get move reply link
2071 *
2072 * Return the move link of the reply
2073 *
2074 * @since 2.3.0 bbPress (r4521)
2075 *
2076 * @param array $args This function supports these arguments:
2077 * - id: Reply id
2078 * - link_before: HTML before the link
2079 * - link_after: HTML after the link
2080 * - move_text: Move text
2081 * - move_title: Move title attribute
2082 * @return string Reply move link
2083 */
2084 function bbp_get_reply_move_link( $args = array() ) {
2085
2086 // Parse arguments against default values
2087 $r = bbp_parse_args( $args, array(
2088 'id' => 0,
2089 'link_before' => '',
2090 'link_after' => '',
2091 'split_text' => esc_html__( 'Move', 'bbpress' ),
2092 'split_title' => esc_attr__( 'Move this reply', 'bbpress' )
2093 ), 'get_reply_move_link' );
2094
2095 // Get IDs
2096 $reply_id = bbp_get_reply_id( $r['id'] );
2097 $topic_id = bbp_get_reply_topic_id( $reply_id );
2098
2099 // Bail if no reply ID or user cannot moderate
2100 if ( empty( $reply_id ) || ! current_user_can( 'moderate', $topic_id ) ) {
2101 return;
2102 }
2103
2104 $uri = add_query_arg( array(
2105 'action' => 'move',
2106 'reply_id' => $reply_id
2107 ), bbp_get_reply_edit_url( $reply_id ) );
2108
2109 $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" title="' . $r['split_title'] . '" class="bbp-reply-move-link">' . $r['split_text'] . '</a>' . $r['link_after'];
2110
2111 // Filter & return
2112 return apply_filters( 'bbp_get_reply_move_link', $retval, $r, $args );
2113 }
2114
2115 /**
2116 * Split topic link
2117 *
2118 * Output the split link of the topic (but is bundled with each reply)
2119 *
2120 * @since 2.0.0 bbPress (r2756)
2121 *
2122 * @param array $args See {@link bbp_get_topic_split_link()}
2123 */
2124 function bbp_topic_split_link( $args = array() ) {
2125 echo bbp_get_topic_split_link( $args );
2126 }
2127
2128 /**
2129 * Get split topic link
2130 *
2131 * Return the split link of the topic (but is bundled with each reply)
2132 *
2133 * @since 2.0.0 bbPress (r2756)
2134 *
2135 * @param array $args This function supports these arguments:
2136 * - id: Reply id
2137 * - link_before: HTML before the link
2138 * - link_after: HTML after the link
2139 * - split_text: Split text
2140 * - split_title: Split title attribute
2141 * @return string Topic split link
2142 */
2143 function bbp_get_topic_split_link( $args = array() ) {
2144
2145 // Parse arguments against default values
2146 $r = bbp_parse_args( $args, array(
2147 'id' => 0,
2148 'link_before' => '',
2149 'link_after' => '',
2150 'split_text' => esc_html__( 'Split', 'bbpress' ),
2151 'split_title' => esc_attr__( 'Split the topic from this reply', 'bbpress' )
2152 ), 'get_topic_split_link' );
2153
2154 // Get IDs
2155 $reply_id = bbp_get_reply_id( $r['id'] );
2156 $topic_id = bbp_get_reply_topic_id( $reply_id );
2157
2158 // Bail if no reply/topic ID, or user cannot moderate
2159 if ( empty( $reply_id ) || empty( $topic_id ) || ! current_user_can( 'moderate', $topic_id ) ) {
2160 return;
2161 }
2162
2163 $uri = add_query_arg( array(
2164 'action' => 'split',
2165 'reply_id' => $reply_id
2166 ), bbp_get_topic_edit_url( $topic_id ) );
2167
2168 $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" title="' . $r['split_title'] . '" class="bbp-topic-split-link">' . $r['split_text'] . '</a>' . $r['link_after'];
2169
2170 // Filter & return
2171 return apply_filters( 'bbp_get_topic_split_link', $retval, $r, $args );
2172 }
2173
2174 /**
2175 * Output the approve link of the reply
2176 *
2177 * @since 2.6.0 bbPress (r5507)
2178 *
2179 * @param array $args See {@link bbp_get_reply_approve_link()}
2180 */
2181 function bbp_reply_approve_link( $args = array() ) {
2182 echo bbp_get_reply_approve_link( $args );
2183 }
2184
2185 /**
2186 * Return the approve link of the reply
2187 *
2188 * @since 2.6.0 bbPress (r5507)
2189 *
2190 * @param array $args This function supports these args:
2191 * - id: Optional. Reply id
2192 * - link_before: Before the link
2193 * - link_after: After the link
2194 * - sep: Separator between links
2195 * - approve_text: Approve text
2196 * - unapprove_text: Unapprove text
2197 * @return string Reply approve link
2198 */
2199 function bbp_get_reply_approve_link( $args = array() ) {
2200
2201 // Parse arguments against default values
2202 $r = bbp_parse_args( $args, array(
2203 'id' => 0,
2204 'link_before' => '',
2205 'link_after' => '',
2206 'sep' => ' | ',
2207 'approve_text' => _x( 'Approve', 'Pending Status', 'bbpress' ),
2208 'unapprove_text' => _x( 'Unapprove', 'Pending Status', 'bbpress' )
2209 ), 'get_reply_approve_link' );
2210
2211 // Get reply
2212 $reply = bbp_get_reply( $r['id'] );
2213
2214 // Bail if no reply or current user cannot moderate
2215 if ( empty( $reply ) || ! current_user_can( 'moderate', $reply->ID ) ) {
2216 return;
2217 }
2218
2219 $display = bbp_is_reply_pending( $reply->ID ) ? $r['approve_text'] : $r['unapprove_text'];
2220 $uri = add_query_arg( array( 'action' => 'bbp_toggle_reply_approve', 'reply_id' => $reply->ID ) );
2221 $uri = wp_nonce_url( $uri, 'approve-reply_' . $reply->ID );
2222 $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" class="bbp-reply-approve-link">' . $display . '</a>' . $r['link_after'];
2223
2224 // Filter & return
2225 return apply_filters( 'bbp_get_reply_approve_link', $retval, $r, $args );
2226 }
2227
2228 /**
2229 * Output the row class of a reply
2230 *
2231 * @since 2.0.0 bbPress (r2678)
2232 *
2233 * @param int $reply_id Optional. Reply ID
2234 * @param array Extra classes you can pass when calling this function
2235 */
2236 function bbp_reply_class( $reply_id = 0, $classes = array() ) {
2237 echo bbp_get_reply_class( $reply_id, $classes );
2238 }
2239 /**
2240 * Return the row class of a reply
2241 *
2242 * @since 2.0.0 bbPress (r2678)
2243 *
2244 * @param int $reply_id Optional. Reply ID
2245 * @param array Extra classes you can pass when calling this function
2246 * @return string Row class of the reply
2247 */
2248 function bbp_get_reply_class( $reply_id = 0, $classes = array() ) {
2249 $bbp = bbpress();
2250 $reply_id = bbp_get_reply_id( $reply_id );
2251 $topic_id = bbp_get_reply_topic_id( $reply_id );
2252 $forum_id = bbp_get_reply_forum_id( $reply_id );
2253 $author_id = bbp_get_reply_author_id( $reply_id );
2254 $reply_pos = bbp_get_reply_position( $reply_id, true );
2255 $classes = array_filter( (array) $classes );
2256 $count = isset( $bbp->reply_query->current_post )
2257 ? (int) $bbp->reply_query->current_post
2258 : 1;
2259
2260 // Stripes
2261 $even_odd = ( $count % 2 )
2262 ? 'even'
2263 : 'odd';
2264
2265 // Forum moderator replied to topic
2266 $forum_moderator = ( bbp_is_user_forum_moderator( $author_id, $forum_id ) === $author_id )
2267 ? 'forum-mod'
2268 : '';
2269
2270 // Topic author replied to others
2271 $topic_author = ( bbp_get_topic_author_id( $topic_id ) === $author_id )
2272 ? 'topic-author'
2273 : '';
2274
2275 // Get reply classes
2276 $reply_classes = array(
2277 'loop-item-' . $count,
2278 'user-id-' . $author_id,
2279 'bbp-parent-forum-' . $forum_id,
2280 'bbp-parent-topic-' . $topic_id,
2281 'bbp-reply-position-' . $reply_pos,
2282 $even_odd,
2283 $topic_author,
2284 $forum_moderator
2285 );
2286
2287 // Run the topic classes through the post-class filters, which also
2288 // handles the escaping of each individual class.
2289 $post_classes = get_post_class( array_merge( $classes, $reply_classes ), $reply_id );
2290
2291 // Filter
2292 $new_classes = apply_filters( 'bbp_get_reply_class', $post_classes, $reply_id, $classes );
2293
2294 // Return
2295 return 'class="' . implode( ' ', $new_classes ) . '"';
2296 }
2297
2298 /** Pagination ****************************************************************/
2299
2300 /**
2301 * Return the base URL used inside of pagination links
2302 *
2303 * @since 2.6.0 bbPress (r6679)
2304 *
2305 * @param int $topic_id
2306 * @return string
2307 */
2308 function bbp_get_replies_pagination_base( $topic_id = 0 ) {
2309
2310 // If pretty permalinks are enabled, make our pagination pretty
2311 if ( bbp_use_pretty_urls() && ! bbp_is_topic_pending( $topic_id )) {
2312
2313 // User's replies
2314 if ( bbp_is_single_user_replies() ) {
2315 $base = bbp_get_user_replies_created_url( bbp_get_displayed_user_id() );
2316
2317 // Root profile page
2318 } elseif ( bbp_is_single_user() ) {
2319 $base = bbp_get_user_profile_url( bbp_get_displayed_user_id() );
2320
2321 // Any single post (for shortcodes)
2322 } elseif ( is_singular() ) {
2323 $base = get_permalink();
2324
2325 // Single topic
2326 } else {
2327 $base = get_permalink( $topic_id );
2328 }
2329
2330 $base = trailingslashit( $base ) . user_trailingslashit( bbp_get_paged_slug() . '/%#%/' );
2331
2332 // Unpretty permalinks
2333 } else {
2334 $base = add_query_arg( 'paged', '%#%' );
2335 }
2336
2337 // Filter & return
2338 return apply_filters( 'bbp_get_replies_pagination_base', $base, $topic_id );
2339 }
2340
2341 /**
2342 * Output the topic pagination count
2343 *
2344 * The results are unescaped by design, to allow them to be filtered freely via
2345 * the 'bbp_get_topic_pagination_count' filter.
2346 *
2347 * @since 2.0.0 bbPress (r2519)
2348 *
2349 */
2350 function bbp_topic_pagination_count() {
2351 echo bbp_get_topic_pagination_count();
2352 }
2353 /**
2354 * Return the topic pagination count
2355 *
2356 * @since 2.0.0 bbPress (r2519)
2357 *
2358 * @return string Topic pagination count
2359 */
2360 function bbp_get_topic_pagination_count() {
2361 $bbp = bbpress();
2362
2363 // Define local variable(s)
2364 $retstr = '';
2365
2366 // Set pagination values
2367 $count_int = intval( $bbp->reply_query->post_count );
2368 $total_int = intval( $bbp->reply_query->found_posts );
2369 $ppp_int = intval( $bbp->reply_query->posts_per_page );
2370 $start_int = intval( ( $bbp->reply_query->paged - 1 ) * $ppp_int ) + 1;
2371 $to_int = intval( ( $start_int + ( $ppp_int - 1 ) > $total_int )
2372 ? $total_int
2373 : $start_int + ( $ppp_int - 1 ) );
2374
2375 // Format numbers for display
2376 $count_num = bbp_number_format( $count_int );
2377 $total_num = bbp_number_format( $total_int );
2378 $from_num = bbp_number_format( $start_int );
2379 $to_num = bbp_number_format( $to_int );
2380
2381 // We are threading replies
2382 if ( bbp_thread_replies() ) {
2383 $walker = new BBP_Walker_Reply();
2384 $threads = absint( $walker->get_number_of_root_elements( $bbp->reply_query->posts ) - 1 );
2385 $retstr = sprintf( _n( 'Viewing %1$s reply thread', 'Viewing %1$s reply threads', $threads, 'bbpress' ), bbp_number_format( $threads ) );
2386
2387 // We are not including the lead topic
2388 } elseif ( bbp_show_lead_topic() ) {
2389
2390 // Several replies in a topic with a single page
2391 if ( empty( $to_num ) ) {
2392 $retstr = sprintf( _n( 'Viewing %1$s reply', 'Viewing %1$s replies', $total_int, 'bbpress' ), $total_num );
2393
2394 // Several replies in a topic with several pages
2395 } else {
2396 $retstr = sprintf( _n( 'Viewing %2$s replies (of %4$s total)', 'Viewing %1$s replies - %2$s through %3$s (of %4$s total)', $count_int, 'bbpress' ), $count_num, $from_num, $to_num, $total_num );
2397 }
2398
2399 // We are including the lead topic
2400 } else {
2401
2402 // Several posts in a topic with a single page
2403 if ( empty( $to_num ) ) {
2404 $retstr = sprintf( _n( 'Viewing %1$s post', 'Viewing %1$s posts', $total_int, 'bbpress' ), $total_num );
2405
2406 // Several posts in a topic with several pages
2407 } else {
2408 $retstr = sprintf( _n( 'Viewing %2$s post (of %4$s total)', 'Viewing %1$s posts - %2$s through %3$s (of %4$s total)', $count_int, 'bbpress' ), $count_num, $from_num, $to_num, $total_num );
2409 }
2410 }
2411
2412 // Escape results of _n()
2413 $retstr = esc_html( $retstr );
2414
2415 // Filter & return
2416 return apply_filters( 'bbp_get_topic_pagination_count', $retstr );
2417 }
2418
2419 /**
2420 * Output topic pagination links
2421 *
2422 * @since 2.0.0 bbPress (r2519)
2423 */
2424 function bbp_topic_pagination_links() {
2425 echo bbp_get_topic_pagination_links();
2426 }
2427 /**
2428 * Return topic pagination links
2429 *
2430 * @since 2.0.0 bbPress (r2519)
2431 *
2432 * @return string Topic pagination links
2433 */
2434 function bbp_get_topic_pagination_links() {
2435 $bbp = bbpress();
2436
2437 if ( ! isset( $bbp->reply_query->pagination_links ) || empty( $bbp->reply_query->pagination_links ) ) {
2438 return false;
2439 }
2440
2441 // Filter & return
2442 return apply_filters( 'bbp_get_topic_pagination_links', $bbp->reply_query->pagination_links );
2443 }
2444
2445 /** Forms *********************************************************************/
2446
2447 /**
2448 * Output the value of reply content field
2449 *
2450 * @since 2.0.0 bbPress (r3130)
2451 */
2452 function bbp_form_reply_content() {
2453 echo bbp_get_form_reply_content();
2454 }
2455 /**
2456 * Return the value of reply content field
2457 *
2458 * @since 2.0.0 bbPress (r3130)
2459 *
2460 * @return string Value of reply content field
2461 */
2462 function bbp_get_form_reply_content() {
2463
2464 // Get _POST data
2465 if ( bbp_is_reply_form_post_request() && isset( $_POST['bbp_reply_content'] ) ) {
2466 $reply_content = wp_unslash( $_POST['bbp_reply_content'] );
2467
2468 // Get edit data
2469 } elseif ( bbp_is_reply_edit() ) {
2470 $reply_content = bbp_get_global_post_field( 'post_content', 'raw' );
2471
2472 // No data
2473 } else {
2474 $reply_content = '';
2475 }
2476
2477 // Filter & return
2478 return apply_filters( 'bbp_get_form_reply_content', $reply_content );
2479 }
2480
2481 /**
2482 * Output the value of the reply to field
2483 *
2484 * @since 2.4.0 bbPress (r4944)
2485 */
2486 function bbp_form_reply_to() {
2487 echo bbp_get_form_reply_to();
2488 }
2489
2490 /**
2491 * Return the value of reply to field
2492 *
2493 * @since 2.4.0 bbPress (r4944)
2494 *
2495 * @return string Value of reply to field
2496 */
2497 function bbp_get_form_reply_to() {
2498
2499 // Set initial value
2500 $reply_to = 0;
2501
2502 // Get $_REQUEST data
2503 if ( isset( $_REQUEST['bbp_reply_to'] ) ) {
2504 $reply_to = bbp_validate_reply_to( $_REQUEST['bbp_reply_to'] );
2505 }
2506
2507 // If empty, get from meta
2508 if ( empty( $reply_to ) ) {
2509 $reply_to = bbp_get_reply_to();
2510 }
2511
2512 // Filter & return
2513 return apply_filters( 'bbp_get_form_reply_to', $reply_to );
2514 }
2515
2516 /**
2517 * Output a select box allowing to pick which reply an existing hierarchical
2518 * reply belongs to.
2519 *
2520 * @since 2.6.0 bbPress (r5387)
2521 *
2522 * @param int $reply_id
2523 */
2524 function bbp_reply_to_dropdown( $reply_id = 0 ) {
2525 echo bbp_get_reply_to_dropdown( $reply_id );
2526 }
2527 /**
2528 * Return a select box allowing to pick which topic/reply a reply belongs.
2529 *
2530 * @since 2.6.0 bbPress (r5387)
2531 *
2532 * @param int $reply_id
2533 *
2534 * @return string The dropdown
2535 */
2536 function bbp_get_reply_to_dropdown( $reply_id = 0 ) {
2537
2538 // Validate the reply data
2539 $reply_id = bbp_get_reply_id( $reply_id );
2540 $reply_to = bbp_get_reply_to( $reply_id );
2541 $topic_id = bbp_get_reply_topic_id( $reply_id );
2542
2543 // Get the replies
2544 $posts = get_posts( array(
2545 'post_type' => bbp_get_reply_post_type(),
2546 'post_status' => bbp_get_public_status_id(),
2547 'post_parent' => $topic_id,
2548 'numberposts' => -1,
2549 'orderby' => 'menu_order',
2550 'order' => 'ASC',
2551 ) );
2552
2553 // Append `reply_to` for each reply so it can be walked
2554 foreach ( $posts as &$post ) {
2555
2556 // Check for reply post type
2557 $_reply_to = bbp_get_reply_to( $post->ID );
2558
2559 // Make sure it's a reply to a reply
2560 if ( empty( $_reply_to ) || ( $topic_id === $_reply_to ) ) {
2561 $_reply_to = 0;
2562 }
2563
2564 // Add reply_to to the post object so we can walk it later
2565 $post->reply_to = $_reply_to;
2566 }
2567
2568 // Default "None" text
2569 $show_none = ( 0 === $reply_id )
2570 ? esc_attr_x( 'None', 'Default reply to dropdown text', 'bbpress' )
2571 : sprintf( esc_attr__( '%1$s - %2$s', 'bbpress' ), $topic_id, bbp_get_topic_title( $topic_id ) );
2572
2573 // Get the dropdown and return it
2574 $retval = bbp_get_dropdown( array(
2575 'show_none' => $show_none,
2576 'select_id' => 'bbp_reply_to',
2577 'select_class' => 'bbp_dropdown',
2578 'exclude' => $reply_id,
2579 'selected' => $reply_to,
2580 'post_parent' => $topic_id,
2581 'post_type' => bbp_get_reply_post_type(),
2582 'max_depth' => bbp_thread_replies_depth(),
2583 'page' => 1,
2584 'per_page' => -1,
2585 'walker' => new BBP_Walker_Reply_Dropdown(),
2586 'posts' => $posts
2587 ) );
2588
2589 // Filter & return
2590 return apply_filters( 'bbp_get_reply_to_dropdown', $retval, $reply_id, $reply_to, $topic_id );
2591 }
2592
2593 /**
2594 * Output checked value of reply log edit field
2595 *
2596 * @since 2.0.0 bbPress (r3130)
2597 */
2598 function bbp_form_reply_log_edit() {
2599 echo bbp_get_form_reply_log_edit();
2600 }
2601 /**
2602 * Return checked value of reply log edit field
2603 *
2604 * @since 2.0.0 bbPress (r3130)
2605 *
2606 * @return string Reply log edit checked value
2607 */
2608 function bbp_get_form_reply_log_edit() {
2609
2610 // Get _POST data
2611 if ( bbp_is_reply_form_post_request() && isset( $_POST['bbp_log_reply_edit'] ) ) {
2612 $reply_revision = (bool) $_POST['bbp_log_reply_edit'];
2613
2614 // No data
2615 } else {
2616 $reply_revision = true;
2617 }
2618
2619 // Get checked output
2620 $checked = checked( $reply_revision, true, false );
2621
2622 // Filter & return
2623 return apply_filters( 'bbp_get_form_reply_log_edit', $checked, $reply_revision );
2624 }
2625
2626 /**
2627 * Output the value of the reply edit reason
2628 *
2629 * @since 2.0.0 bbPress (r3130)
2630 */
2631 function bbp_form_reply_edit_reason() {
2632 echo bbp_get_form_reply_edit_reason();
2633 }
2634 /**
2635 * Return the value of the reply edit reason
2636 *
2637 * @since 2.0.0 bbPress (r3130)
2638 *
2639 * @return string Reply edit reason value
2640 */
2641 function bbp_get_form_reply_edit_reason() {
2642
2643 // Get _POST data
2644 if ( bbp_is_reply_form_post_request() && isset( $_POST['bbp_reply_edit_reason'] ) ) {
2645 $reply_edit_reason = wp_unslash( $_POST['bbp_reply_edit_reason'] );
2646
2647 // No data
2648 } else {
2649 $reply_edit_reason = '';
2650 }
2651
2652 // Filter & return
2653 return apply_filters( 'bbp_get_form_reply_edit_reason', $reply_edit_reason );
2654 }
2655
2656 /**
2657 * Output value reply status dropdown
2658 *
2659 * @since 2.6.0 bbPress (r5399)
2660 *
2661 * @param $args This function supports these arguments:
2662 * - select_id: Select id. Defaults to bbp_reply_status
2663 * - tab: Deprecated. Tabindex
2664 * - reply_id: Reply id
2665 * - selected: Override the selected option
2666 */
2667 function bbp_form_reply_status_dropdown( $args = array() ) {
2668 echo bbp_get_form_reply_status_dropdown( $args );
2669 }
2670 /**
2671 * Returns reply status dropdown
2672 *
2673 * This dropdown is only intended to be seen by users with the 'moderate'
2674 * capability. Because of this, no additional capability checks are performed
2675 * within this function to check available reply statuses.
2676 *
2677 * @since 2.6.0 bbPress (r5399)
2678 *
2679 * @param $args This function supports these arguments:
2680 * - select_id: Select id. Defaults to bbp_reply_status
2681 * - tab: Deprecated. Tabindex
2682 * - reply_id: Reply id
2683 * - selected: Override the selected option
2684 */
2685 function bbp_get_form_reply_status_dropdown( $args = array() ) {
2686
2687 // Parse arguments against default values
2688 $r = bbp_parse_args( $args, array(
2689 'select_id' => 'bbp_reply_status',
2690 'select_class' => 'bbp_dropdown',
2691 'tab' => false,
2692 'reply_id' => 0,
2693 'selected' => false
2694 ), 'reply_status_dropdown' );
2695
2696 // No specific selected value passed
2697 if ( empty( $r['selected'] ) ) {
2698
2699 // Post value is passed
2700 if ( bbp_is_reply_form_post_request() && isset( $_POST[ $r['select_id'] ] ) ) {
2701 $r['selected'] = sanitize_key( $_POST[ $r['select_id'] ] );
2702
2703 // No Post value was passed
2704 } else {
2705
2706 // Edit reply
2707 if ( bbp_is_reply_edit() ) {
2708 $r['reply_id'] = bbp_get_reply_id( $r['reply_id'] );
2709 $r['selected'] = bbp_get_reply_status( $r['reply_id'] );
2710
2711 // New reply
2712 } else {
2713 $r['selected'] = bbp_get_public_status_id();
2714 }
2715 }
2716 }
2717
2718 // Start an output buffer, we'll finish it after the select loop
2719 ob_start(); ?>
2720
2721 <select name="<?php echo esc_attr( $r['select_id'] ) ?>" id="<?php echo esc_attr( $r['select_id'] ); ?>_select" class="<?php echo esc_attr( $r['select_class'] ); ?>"<?php bbp_tab_index_attribute( $r['tab'] ); ?>>
2722
2723 <?php foreach ( bbp_get_reply_statuses( $r['reply_id'] ) as $key => $label ) : ?>
2724
2725 <option value="<?php echo esc_attr( $key ); ?>"<?php selected( $key, $r['selected'] ); ?>><?php echo esc_html( $label ); ?></option>
2726
2727 <?php endforeach; ?>
2728
2729 </select>
2730
2731 <?php
2732
2733 // Filter & return
2734 return apply_filters( 'bbp_get_form_reply_status_dropdown', ob_get_clean(), $r, $args );
2735 }
2736
2737 /**
2738 * Verify if a POST request came from a failed reply attempt.
2739 *
2740 * Used to avoid cross-site request forgeries when checking posted reply form
2741 * content.
2742 *
2743 * @see bbp_reply_form_fields()
2744 *
2745 * @since 2.6.0 bbPress (r5558)
2746 *
2747 * @return boolean True if is a post request with valid nonce
2748 */
2749 function bbp_is_reply_form_post_request() {
2750
2751 // Bail if not a post request
2752 if ( ! bbp_is_post_request() ) {
2753 return false;
2754 }
2755
2756 // Creating a new reply
2757 if ( bbp_verify_nonce_request( 'bbp-new-reply' ) ) {
2758 return true;
2759 }
2760
2761 // Editing an existing reply
2762 if ( bbp_verify_nonce_request( 'bbp-edit-reply' ) ) {
2763 return true;
2764 }
2765
2766 return false;
2767 }
2768