PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / 2.5.0
Forumax – AI Powered Advanced Community Forum Plugin v2.5.0
2.5.0 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 All 30 releases
bbp-core / lib / bbpress / includes / replies / template.php

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

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