PluginProbe
bbPress / 2.6.6
bbPress v2.6.6
trunk 2.0 2.0-beta-1 2.0-beta-2b 2.0-beta-3 2.0-beta-3b 2.0-rc-2 2.0-rc-3 2.0-rc-4 2.0-rc-5 2.0.1 2.0.2 2.0.3 2.1 2.1-beta-1 2.1-rc1 2.1-rc2 2.1-rc3 2.1-rc4 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.2.2 All 71 releases
bbpress / includes / topics / template.php

template.php in bbPress 2.6.6, at includes/topics/template.php

4,030 lines 115.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * bbPress Topic 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 * Output the unique id of the custom post type for topics
17 *
18 * @since 2.0.0 bbPress (r2857)
19 */
20 function bbp_topic_post_type() {
21 echo bbp_get_topic_post_type();
22 }
23 /**
24 * Return the unique id of the custom post type for topics
25 *
26 * @since 2.0.0 bbPress (r2857)
27 *
28 * @return string The unique topic post type id
29 */
30 function bbp_get_topic_post_type() {
31
32 // Filter & return
33 return apply_filters( 'bbp_get_topic_post_type', bbpress()->topic_post_type );
34 }
35
36 /**
37 * Return array of labels used by the topic post type
38 *
39 * @since 2.5.0 bbPress (r5129)
40 *
41 * @return array
42 */
43 function bbp_get_topic_post_type_labels() {
44
45 // Filter & return
46 return (array) apply_filters( 'bbp_get_topic_post_type_labels', array(
47 'name' => esc_attr__( 'Topics', 'bbpress' ),
48 'menu_name' => esc_attr__( 'Topics', 'bbpress' ),
49 'singular_name' => esc_attr__( 'Topic', 'bbpress' ),
50 'all_items' => esc_attr__( 'All Topics', 'bbpress' ),
51 'add_new' => esc_attr__( 'Add New', 'bbpress' ),
52 'add_new_item' => esc_attr__( 'Create New Topic', 'bbpress' ),
53 'edit' => esc_attr__( 'Edit', 'bbpress' ),
54 'edit_item' => esc_attr__( 'Edit Topic', 'bbpress' ),
55 'new_item' => esc_attr__( 'New Topic', 'bbpress' ),
56 'view' => esc_attr__( 'View Topic', 'bbpress' ),
57 'view_item' => esc_attr__( 'View Topic', 'bbpress' ),
58 'view_items' => esc_attr__( 'View Topics', 'bbpress' ),
59 'search_items' => esc_attr__( 'Search Topics', 'bbpress' ),
60 'not_found' => esc_attr__( 'No topics found', 'bbpress' ),
61 'not_found_in_trash' => esc_attr__( 'No topics found in Trash', 'bbpress' ),
62 'filter_items_list' => esc_attr__( 'Filter topics list', 'bbpress' ),
63 'items_list' => esc_attr__( 'Topics list', 'bbpress' ),
64 'items_list_navigation' => esc_attr__( 'Topics list navigation', 'bbpress' ),
65 'parent_item_colon' => esc_attr__( 'Forum:', 'bbpress' ),
66 'archives' => esc_attr__( 'Forum Topics', 'bbpress' ),
67 'attributes' => esc_attr__( 'Topic Attributes', 'bbpress' ),
68 'insert_into_item' => esc_attr__( 'Insert into topic', 'bbpress' ),
69 'uploaded_to_this_item' => esc_attr__( 'Uploaded to this topic', 'bbpress' ),
70 'featured_image' => esc_attr__( 'Topic Image', 'bbpress' ),
71 'set_featured_image' => esc_attr__( 'Set topic image', 'bbpress' ),
72 'remove_featured_image' => esc_attr__( 'Remove topic image', 'bbpress' ),
73 'use_featured_image' => esc_attr__( 'Use as topic image', 'bbpress' ),
74 'item_published' => esc_attr__( 'Topic published.', 'bbpress' ),
75 'item_published_privately' => esc_attr__( 'Topic published privately.', 'bbpress' ),
76 'item_reverted_to_draft' => esc_attr__( 'Topic reverted to draft.', 'bbpress' ),
77 'item_scheduled' => esc_attr__( 'Topic scheduled.', 'bbpress' ),
78 'item_updated' => esc_attr__( 'Topic updated.', 'bbpress' )
79 ) );
80 }
81
82 /**
83 * Return array of topic post type rewrite settings
84 *
85 * @since 2.5.0 bbPress (r5129)
86 *
87 * @return array
88 */
89 function bbp_get_topic_post_type_rewrite() {
90
91 // Filter & return
92 return (array) apply_filters( 'bbp_get_topic_post_type_rewrite', array(
93 'slug' => bbp_get_topic_slug(),
94 'with_front' => false
95 ) );
96 }
97
98 /**
99 * Return array of features the topic post type supports
100 *
101 * @since 2.5.0 bbPress (r5129)
102 *
103 * @return array
104 */
105 function bbp_get_topic_post_type_supports() {
106
107 // Filter & return
108 return (array) apply_filters( 'bbp_get_topic_post_type_supports', array(
109 'title',
110 'editor',
111 'revisions'
112 ) );
113 }
114
115 /**
116 * The plugin version of bbPress comes with two topic display options:
117 * - Traditional: Topics are included in the reply loop (default)
118 * - New Style: Topics appear as "lead" posts, ahead of replies
119 *
120 * @since 2.0.0 bbPress (r2954)
121 *
122 * @param $show_lead Optional. Default false
123 * @return bool Yes if the topic appears as a lead, otherwise false
124 */
125 function bbp_show_lead_topic( $show_lead = false ) {
126
127 // Never separate the lead topic in feeds
128 if ( is_feed() ) {
129 return false;
130 }
131
132 // Filter & return
133 return (bool) apply_filters( 'bbp_show_lead_topic', (bool) $show_lead );
134 }
135
136 /** Topic Loop ****************************************************************/
137
138 /**
139 * The main topic loop. WordPress makes this easy for us
140 *
141 * @since 2.0.0 bbPress (r2485)
142 *
143 * @param array $args All the arguments supported by {@link WP_Query}
144 * @return object Multidimensional array of topic information
145 */
146 function bbp_has_topics( $args = array() ) {
147
148 /** Defaults **************************************************************/
149
150 // Other defaults
151 $default_topic_search = bbp_sanitize_search_request( 'ts' );
152 $default_show_stickies = (bool) ( bbp_is_single_forum() || bbp_is_topic_archive() ) && ( false === $default_topic_search );
153 $default_post_parent = bbp_is_single_forum() ? bbp_get_forum_id() : 'any';
154
155 // Default argument array
156 $default = array(
157 'post_type' => bbp_get_topic_post_type(), // Narrow query down to bbPress topics
158 'post_parent' => $default_post_parent, // Forum ID
159 'meta_key' => '_bbp_last_active_time', // Make sure topic has some last activity time
160 'meta_type' => 'DATETIME',
161 'orderby' => 'meta_value', // 'meta_value', 'author', 'date', 'title', 'modified', 'parent', rand',
162 'order' => 'DESC', // 'ASC', 'DESC'
163 'posts_per_page' => bbp_get_topics_per_page(), // Topics per page
164 'paged' => bbp_get_paged(), // Page Number
165 'show_stickies' => $default_show_stickies, // Ignore sticky topics?
166 'max_num_pages' => false, // Maximum number of pages to show
167
168 // Conditionally prime the cache for related posts
169 'update_post_family_cache' => true
170 );
171
172 // Only add 's' arg if searching for topics
173 // See https://bbpress.trac.wordpress.org/ticket/2607
174 if ( ! empty( $default_topic_search ) ) {
175 $default['s'] = $default_topic_search;
176 }
177
178 // What are the default allowed statuses (based on user caps)
179 if ( bbp_get_view_all( 'edit_others_topics' ) ) {
180
181 // Default view=all statuses
182 $post_statuses = array_keys( bbp_get_topic_statuses() );
183
184 // Add support for private status
185 if ( current_user_can( 'read_private_topics' ) ) {
186 $post_statuses[] = bbp_get_private_status_id();
187 }
188
189 // Join post statuses together
190 $default['post_status'] = $post_statuses;
191
192 // Lean on the 'perm' query var value of 'readable' to provide statuses
193 } else {
194 $default['perm'] = 'readable';
195 }
196
197 // Maybe query for topic tags
198 if ( bbp_is_topic_tag() ) {
199 $default['term'] = bbp_get_topic_tag_slug();
200 $default['taxonomy'] = bbp_get_topic_tag_tax_id();
201 }
202
203 /** Setup *****************************************************************/
204
205 // Parse arguments against default values
206 $r = bbp_parse_args( $args, $default, 'has_topics' );
207
208 // Get bbPress
209 $bbp = bbpress();
210
211 // Call the query
212 $bbp->topic_query = new WP_Query( $r );
213
214 // Maybe prime last active posts
215 if ( ! empty( $r['update_post_family_cache'] ) ) {
216 bbp_update_post_family_caches( $bbp->topic_query->posts );
217 }
218
219 // Set post_parent back to 0 if originally set to 'any'
220 if ( 'any' === $r['post_parent'] ) {
221 $r['post_parent'] = 0;
222 }
223
224 // Limited the number of pages shown
225 if ( ! empty( $r['max_num_pages'] ) ) {
226 $bbp->topic_query->max_num_pages = (int) $r['max_num_pages'];
227 }
228
229 /** Stickies **************************************************************/
230
231 // Put sticky posts at the top of the posts array
232 if ( ! empty( $r['show_stickies'] ) && ( $r['paged'] <= 1 ) ) {
233 bbp_add_sticky_topics( $bbp->topic_query, $r );
234 }
235
236 // If no limit to posts per page, set it to the current post_count
237 if ( -1 === $r['posts_per_page'] ) {
238 $r['posts_per_page'] = $bbp->topic_query->post_count;
239 }
240
241 // Add pagination values to query object
242 $bbp->topic_query->posts_per_page = (int) $r['posts_per_page'];
243 $bbp->topic_query->paged = (int) $r['paged'];
244
245 // Only add pagination if query returned results
246 if ( ( ! empty( $bbp->topic_query->post_count ) || ! empty( $bbp->topic_query->found_posts ) ) && ! empty( $bbp->topic_query->posts_per_page ) ) {
247
248 // Limit the number of topics shown based on maximum allowed pages
249 if ( ( ! empty( $r['max_num_pages'] ) ) && ( $bbp->topic_query->found_posts > ( $bbp->topic_query->max_num_pages * $bbp->topic_query->post_count ) ) ) {
250 $bbp->topic_query->found_posts = $bbp->topic_query->max_num_pages * $bbp->topic_query->post_count;
251 }
252
253 // Total topics for pagination boundaries
254 $total_pages = ( $bbp->topic_query->posts_per_page === $bbp->topic_query->found_posts )
255 ? 1
256 : ceil( $bbp->topic_query->found_posts / $bbp->topic_query->posts_per_page );
257
258 // Maybe add view-all args
259 $add_args = bbp_get_view_all()
260 ? array( 'view' => 'all' )
261 : false;
262
263 // Pagination settings with filter
264 $bbp_topic_pagination = apply_filters( 'bbp_topic_pagination', array(
265 'base' => bbp_get_topics_pagination_base( $r['post_parent'] ),
266 'format' => '',
267 'total' => $total_pages,
268 'current' => $bbp->topic_query->paged,
269 'prev_text' => is_rtl() ? '&rarr;' : '&larr;',
270 'next_text' => is_rtl() ? '&larr;' : '&rarr;',
271 'mid_size' => 1,
272 'add_args' => $add_args,
273 ) );
274
275 // Add pagination to query object
276 $bbp->topic_query->pagination_links = bbp_paginate_links( $bbp_topic_pagination );
277 }
278
279 // Filter & return
280 return apply_filters( 'bbp_has_topics', $bbp->topic_query->have_posts(), $bbp->topic_query );
281 }
282
283 /**
284 * Whether there are more topics available in the loop
285 *
286 * @since 2.0.0 bbPress (r2485)
287 *
288 * @return object Topic information
289 */
290 function bbp_topics() {
291
292 // Put into variable to check against next
293 $have_posts = bbpress()->topic_query->have_posts();
294
295 // Reset the post data when finished
296 if ( empty( $have_posts ) ) {
297 wp_reset_postdata();
298 }
299
300 return $have_posts;
301 }
302
303 /**
304 * Loads up the current topic in the loop
305 *
306 * @since 2.0.0 bbPress (r2485)
307 *
308 * @return object Topic information
309 */
310 function bbp_the_topic() {
311 return bbpress()->topic_query->the_post();
312 }
313
314 /**
315 * Add sticky topics to a topics query object
316 *
317 * @since 2.6.0 bbPress (r6402)
318 *
319 * @param WP_Query $query
320 * @param array $args
321 */
322 function bbp_add_sticky_topics( &$query, $args = array() ) {
323
324 // Bail if intercepted
325 $intercept = bbp_maybe_intercept( __FUNCTION__, func_get_args() );
326 if ( bbp_is_intercepted( $intercept ) ) {
327 return $intercept;
328 }
329
330 // Parse arguments against what gets used locally
331 $r = bbp_parse_args( $args, array(
332 'post_parent' => 0,
333 'post_parent__not_in' => array(),
334 'post__not_in' => array(),
335 'post_status' => '',
336 'perm' => ''
337 ), 'add_sticky_topics' );
338
339 // Get super stickies and stickies in this forum
340 $super_stickies = bbp_get_super_stickies();
341 $forum_stickies = ! empty( $r['post_parent'] )
342 ? bbp_get_stickies( $r['post_parent'] )
343 : array();
344
345 // Merge stickies (supers first) and remove duplicates
346 $stickies = array_filter( array_unique( array_merge( $super_stickies, $forum_stickies ) ) );
347
348 // Bail if no stickies
349 if ( empty( $stickies ) ) {
350 return;
351 }
352
353 // If any posts have been excluded specifically, Ignore those that are sticky.
354 if ( ! empty( $r['post__not_in'] ) ) {
355 $stickies = array_diff( $stickies, $r['post__not_in'] );
356 }
357
358 // Default sticky posts array
359 $sticky_topics = array();
360
361 // Loop through posts
362 foreach ( $query->posts as $key => $post ) {
363
364 // Looking for stickies in this query loop, and stash & unset them
365 if ( in_array( $post->ID, $stickies, true ) ) {
366 $sticky_topics[] = $post;
367 unset( $query->posts[ $key ] );
368 }
369 }
370
371 // Remove queried stickies from stickies array
372 if ( ! empty( $sticky_topics ) ) {
373 $stickies = array_diff( $stickies, wp_list_pluck( $sticky_topics, 'ID' ) );
374 }
375
376 // Fetch all stickies that were not in the query
377 if ( ! empty( $stickies ) ) {
378
379 // Query to use in get_posts to get sticky posts
380 $sticky_query = array(
381 'post_type' => bbp_get_topic_post_type(),
382 'post_parent' => 'any',
383 'meta_key' => '_bbp_last_active_time',
384 'meta_type' => 'DATETIME',
385 'orderby' => 'meta_value',
386 'order' => 'DESC',
387 'include' => $stickies
388 );
389
390 // Conditionally exclude private/hidden forum ID's
391 $exclude_forum_ids = bbp_exclude_forum_ids( 'array' );
392
393 // Maybe remove the current forum from excluded forum IDs
394 if ( ! empty( $r['post_parent' ] ) ) {
395 unset( $exclude_forum_ids[ $r['post_parent' ] ] );
396 }
397
398 // Maybe exclude specific forums
399 if ( ! empty( $exclude_forum_ids ) ) {
400 $sticky_query['post_parent__not_in'] = $exclude_forum_ids;
401 }
402
403 // Allowed statuses, or lean on the 'perm' argument (probably 'readable')
404 $sticky_query['post_status'] = bbp_get_view_all( 'edit_others_topics' )
405 ? $r['post_status']
406 : $r['perm'];
407
408 // Get unqueried stickies
409 $_posts = get_posts( $sticky_query );
410 if ( ! empty( $_posts ) ) {
411
412 // Merge the stickies topics with the query topics .
413 $sticky_topics = array_merge( $sticky_topics, $_posts );
414
415 // Get a count of the visible stickies
416 $sticky_count = count( $_posts );
417
418 // Adjust loop and counts for new sticky positions
419 $query->found_posts = (int) $query->found_posts + (int) $sticky_count;
420 $query->post_count = (int) $query->post_count + (int) $sticky_count;
421 }
422 }
423
424 // Bail if no sticky topics empty or not an array
425 if ( empty( $sticky_topics ) || ! is_array( $sticky_topics ) ) {
426 return;
427 }
428
429 // Default ordered stickies array
430 $ordered_stickies = array(
431 'supers' => array(),
432 'forums' => array()
433 );
434
435 // Separate supers from forums
436 foreach ( $sticky_topics as $post ) {
437 if ( in_array( $post->ID, $super_stickies, true ) ) {
438 $ordered_stickies['supers'][] = $post;
439 } elseif ( in_array( $post->ID, $forum_stickies, true ) ) {
440 $ordered_stickies['forums'][] = $post;
441 }
442 }
443
444 // Merge supers and forums, supers first
445 $sticky_topics = array_merge( $ordered_stickies['supers'], $ordered_stickies['forums'] );
446
447 // Update queried posts
448 $query->posts = array_merge( $sticky_topics, array_values( $query->posts ) );
449 }
450
451 /**
452 * Output the topic id
453 *
454 * @since 2.0.0 bbPress (r2485)
455 */
456 function bbp_topic_id( $topic_id = 0) {
457 echo bbp_get_topic_id( $topic_id );
458 }
459 /**
460 * Return the topic id
461 *
462 * @since 2.0.0 bbPress (r2485)
463 *
464 * @param $topic_id Optional. Used to check emptiness
465 * @return int The topic id
466 */
467 function bbp_get_topic_id( $topic_id = 0 ) {
468 $bbp = bbpress();
469 $wp_query = bbp_get_wp_query();
470
471 // Easy empty checking
472 if ( ! empty( $topic_id ) && is_numeric( $topic_id ) ) {
473 $bbp_topic_id = $topic_id;
474
475 // Currently inside a topic loop
476 } elseif ( ! empty( $bbp->topic_query->in_the_loop ) && isset( $bbp->topic_query->post->ID ) ) {
477 $bbp_topic_id = $bbp->topic_query->post->ID;
478
479 // Currently inside a search loop
480 } elseif ( ! empty( $bbp->search_query->in_the_loop ) && isset( $bbp->search_query->post->ID ) && bbp_is_topic( $bbp->search_query->post->ID ) ) {
481 $bbp_topic_id = $bbp->search_query->post->ID;
482
483 // Currently viewing/editing a topic, likely alone
484 } elseif ( ( bbp_is_single_topic() || bbp_is_topic_edit() ) && ! empty( $bbp->current_topic_id ) ) {
485 $bbp_topic_id = $bbp->current_topic_id;
486
487 // Currently viewing/editing a topic, likely in a loop
488 } elseif ( ( bbp_is_single_topic() || bbp_is_topic_edit() ) && isset( $wp_query->post->ID ) ) {
489 $bbp_topic_id = $wp_query->post->ID;
490
491 // Currently viewing/editing a reply
492 } elseif ( bbp_is_single_reply() || bbp_is_reply_edit() ) {
493 $bbp_topic_id = bbp_get_reply_topic_id();
494
495 // Fallback
496 } else {
497 $bbp_topic_id = 0;
498 }
499
500 // Filter & return
501 return (int) apply_filters( 'bbp_get_topic_id', (int) $bbp_topic_id, $topic_id );
502 }
503
504 /**
505 * Gets a topic
506 *
507 * @since 2.0.0 bbPress (r2787)
508 *
509 * @return mixed Null if error or topic (in specified form) if success
510 */
511 function bbp_get_topic( $topic, $output = OBJECT, $filter = 'raw' ) {
512
513 // Maybe get ID from empty or int
514 if ( empty( $topic ) || is_numeric( $topic ) ) {
515 $topic = bbp_get_topic_id( $topic );
516 }
517
518 // Bail if no post object
519 $topic = get_post( $topic, OBJECT, $filter );
520 if ( empty( $topic ) ) {
521 return $topic;
522 }
523
524 // Bail if not correct post type
525 if ( $topic->post_type !== bbp_get_topic_post_type() ) {
526 return null;
527 }
528
529 // Default return value is OBJECT
530 $retval = $topic;
531
532 // Array A
533 if ( $output === ARRAY_A ) {
534 $retval = get_object_vars( $topic );
535
536 // Array N
537 } elseif ( $output === ARRAY_N ) {
538 $retval = array_values( get_object_vars( $topic ) );
539 }
540
541 // Filter & return
542 return apply_filters( 'bbp_get_topic', $retval, $topic, $output, $filter );
543 }
544
545 /**
546 * Output the link to the topic in the topic loop
547 *
548 * @since 2.0.0 bbPress (r2485)
549 *
550 * @param int $topic_id Optional. Topic id
551 * @param string $redirect_to Optional. Pass a redirect value for use with
552 * shortcodes and other fun things.
553 */
554 function bbp_topic_permalink( $topic_id = 0, $redirect_to = '' ) {
555 echo esc_url( bbp_get_topic_permalink( $topic_id, $redirect_to ) );
556 }
557 /**
558 * Return the link to the topic
559 *
560 * @since 2.0.0 bbPress (r2485)
561 *
562 * @param int $topic_id Optional. Topic id
563 * @param string $redirect_to Optional. Pass a redirect value for use with
564 * shortcodes and other fun things.
565 * @return string Permanent link to topic
566 */
567 function bbp_get_topic_permalink( $topic_id = 0, $redirect_to = '' ) {
568 $topic_id = bbp_get_topic_id( $topic_id );
569
570 // Use the redirect address
571 if ( ! empty( $redirect_to ) ) {
572 $topic_permalink = esc_url_raw( $redirect_to );
573
574 // Use the topic permalink
575 } else {
576 $topic_permalink = get_permalink( $topic_id );
577 }
578
579 // Filter & return
580 return apply_filters( 'bbp_get_topic_permalink', $topic_permalink, $topic_id );
581 }
582
583 /**
584 * Output the title of the topic
585 *
586 * @since 2.0.0 bbPress (r2485)
587 *
588 * @param int $topic_id Optional. Topic id
589 */
590 function bbp_topic_title( $topic_id = 0 ) {
591 echo bbp_get_topic_title( $topic_id );
592 }
593 /**
594 * Return the title of the topic
595 *
596 * @since 2.0.0 bbPress (r2485)
597 *
598 * @param int $topic_id Optional. Topic id
599 * @return string Title of topic
600 */
601 function bbp_get_topic_title( $topic_id = 0 ) {
602 $topic_id = bbp_get_topic_id( $topic_id );
603 $title = get_the_title( $topic_id );
604
605 // Filter & return
606 return apply_filters( 'bbp_get_topic_title', $title, $topic_id );
607 }
608
609 /**
610 * Output the topic archive title
611 *
612 * @since 2.0.0 bbPress (r3249)
613 *
614 * @param string $title Default text to use as title
615 */
616 function bbp_topic_archive_title( $title = '' ) {
617 echo bbp_get_topic_archive_title( $title );
618 }
619 /**
620 * Return the topic archive title
621 *
622 * @since 2.0.0 bbPress (r3249)
623 *
624 * @param string $title Default text to use as title
625 *
626 * @return string The topic archive title
627 */
628 function bbp_get_topic_archive_title( $title = '' ) {
629
630 // If no title was passed
631 if ( empty( $title ) ) {
632
633 // Set root text to page title
634 $page = bbp_get_page_by_path( bbp_get_topic_archive_slug() );
635 if ( ! empty( $page ) ) {
636 $title = get_the_title( $page->ID );
637
638 // Default to topic post type name label
639 } else {
640 $tto = get_post_type_object( bbp_get_topic_post_type() );
641 $title = $tto->labels->name;
642 }
643 }
644
645 // Filter & return
646 return apply_filters( 'bbp_get_topic_archive_title', $title );
647 }
648
649 /**
650 * Output the content of the topic
651 *
652 * @since 2.0.0 bbPress (r2780)
653 *
654 * @param int $topic_id Optional. Topic id
655 */
656 function bbp_topic_content( $topic_id = 0 ) {
657 echo bbp_get_topic_content( $topic_id );
658 }
659 /**
660 * Return the content of the topic
661 *
662 * @since 2.0.0 bbPress (r2780)
663 *
664 * @param int $topic_id Optional. Topic id
665 * @return string Content of the topic
666 */
667 function bbp_get_topic_content( $topic_id = 0 ) {
668 $topic_id = bbp_get_topic_id( $topic_id );
669
670 // Check if password is required
671 if ( post_password_required( $topic_id ) ) {
672 return get_the_password_form();
673 }
674
675 $content = get_post_field( 'post_content', $topic_id );
676
677 // Filter & return
678 return apply_filters( 'bbp_get_topic_content', $content, $topic_id );
679 }
680
681 /**
682 * Output the excerpt of the topic
683 *
684 * @since 2.0.0 bbPress (r2780)
685 *
686 * @param int $topic_id Optional. Topic id
687 * @param int $length Optional. Length of the excerpt. Defaults to 100 letters
688 */
689 function bbp_topic_excerpt( $topic_id = 0, $length = 100 ) {
690 echo bbp_get_topic_excerpt( $topic_id, $length );
691 }
692 /**
693 * Return the excerpt of the topic
694 *
695 * @since 2.0.0 bbPress (r2780)
696 *
697 * @param int $topic_id Optional. topic id
698 * @param int $length Optional. Length of the excerpt. Defaults to 100
699 * letters
700 * @return string topic Excerpt
701 */
702 function bbp_get_topic_excerpt( $topic_id = 0, $length = 100 ) {
703 $topic_id = bbp_get_topic_id( $topic_id );
704 $length = (int) $length;
705 $excerpt = get_post_field( 'post_excerpt', $topic_id );
706
707 if ( empty( $excerpt ) ) {
708 $excerpt = bbp_get_topic_content( $topic_id );
709 }
710
711 $excerpt = trim( strip_tags( $excerpt ) );
712
713 // Multibyte support
714 if ( function_exists( 'mb_strlen' ) ) {
715 $excerpt_length = mb_strlen( $excerpt );
716 } else {
717 $excerpt_length = strlen( $excerpt );
718 }
719
720 if ( ! empty( $length ) && ( $excerpt_length > $length ) ) {
721 $excerpt = mb_substr( $excerpt, 0, $length - 1 );
722 $excerpt .= '&hellip;';
723 }
724
725 // Filter & return
726 return apply_filters( 'bbp_get_topic_excerpt', $excerpt, $topic_id, $length );
727 }
728
729 /**
730 * Output the post date and time of a topic
731 *
732 * @since 2.2.0 bbPress (r4155)
733 *
734 * @param int $topic_id Optional. Topic id.
735 * @param bool $humanize Optional. Humanize output using time_since
736 * @param bool $gmt Optional. Use GMT
737 */
738 function bbp_topic_post_date( $topic_id = 0, $humanize = false, $gmt = false ) {
739 echo bbp_get_topic_post_date( $topic_id, $humanize, $gmt );
740 }
741 /**
742 * Return the post date and time of a topic
743 *
744 * @since 2.2.0 bbPress (r4155)
745 *
746 * @param int $topic_id Optional. Topic id.
747 * @param bool $humanize Optional. Humanize output using time_since
748 * @param bool $gmt Optional. Use GMT
749 * @return string
750 */
751 function bbp_get_topic_post_date( $topic_id = 0, $humanize = false, $gmt = false ) {
752 $topic_id = bbp_get_topic_id( $topic_id );
753
754 // 4 days, 4 hours ago
755 if ( ! empty( $humanize ) ) {
756 $gmt_s = ! empty( $gmt ) ? 'G' : 'U';
757 $date = get_post_time( $gmt_s, $gmt, $topic_id );
758 $time = false; // For filter below
759 $result = bbp_get_time_since( $date );
760
761 // August 4, 2012 at 2:37 pm
762 } else {
763 $date = get_post_time( get_option( 'date_format' ), $gmt, $topic_id, true );
764 $time = get_post_time( get_option( 'time_format' ), $gmt, $topic_id, true );
765 $result = sprintf( _x( '%1$s at %2$s', 'date at time', 'bbpress' ), $date, $time );
766 }
767
768 // Filter & return
769 return apply_filters( 'bbp_get_topic_post_date', $result, $topic_id, $humanize, $gmt, $date, $time );
770 }
771
772 /**
773 * Output pagination links of a topic within the topic loop
774 *
775 * @since 2.0.0 bbPress (r2966)
776 *
777 * @param array $args See {@link bbp_get_topic_pagination()}
778 */
779 function bbp_topic_pagination( $args = array() ) {
780 echo bbp_get_topic_pagination( $args );
781 }
782 /**
783 * Returns pagination links of a topic within the topic loop
784 *
785 * @since 2.0.0 bbPress (r2966)
786 *
787 * @param array $args This function supports these arguments:
788 * - topic_id: Topic id
789 * - before: Before the links
790 * - after: After the links
791 * @return string Pagination links
792 */
793 function bbp_get_topic_pagination( $args = array() ) {
794
795 // Bail if threading replies
796 if ( bbp_thread_replies() ) {
797 return;
798 }
799
800 // Parse arguments against default values
801 $r = bbp_parse_args( $args, array(
802 'topic_id' => bbp_get_topic_id(),
803 'before' => '<span class="bbp-topic-pagination">',
804 'after' => '</span>',
805 ), 'get_topic_pagination' );
806
807 // Slug must be checked for topics that have never been approved/published
808 $has_slug = bbp_get_topic( $r['topic_id'] )->post_name;
809
810 // If pretty permalinks are enabled, make our pagination pretty
811 $base = ! empty( $has_slug ) && bbp_use_pretty_urls() && ! bbp_is_topic_pending( $r['topic_id'] )
812 ? trailingslashit( get_permalink( $r['topic_id'] ) ) . user_trailingslashit( bbp_get_paged_slug() . '/%#%/' )
813 : add_query_arg( 'paged', '%#%', get_permalink( $r['topic_id'] ) );
814
815 // Get total and add 1 if topic is included in the reply loop
816 $total = bbp_get_topic_reply_count( $r['topic_id'], true );
817
818 // Bump if topic is in loop
819 if ( ! bbp_show_lead_topic() ) {
820 $total++;
821 }
822
823 // Total for pagination boundaries
824 $total_pages = ceil( $total / bbp_get_replies_per_page() );
825
826 // Maybe add view-all args
827 $add_args = bbp_get_view_all( 'edit_others_replies' )
828 ? array( 'view' => 'all' )
829 : false;
830
831 // Pagination settings with filter
832 $bbp_topic_pagination = apply_filters( 'bbp_get_topic_pagination', array(
833 'base' => $base,
834 'total' => $total_pages,
835 'current' => 0,
836 'prev_next' => false,
837 'mid_size' => 2,
838 'end_size' => 2,
839 'add_args' => $add_args
840 ) );
841
842 // Add pagination to query object
843 $pagination_links = bbp_paginate_links( $bbp_topic_pagination );
844
845 // Maybe add before and after to pagination links
846 if ( ! empty( $pagination_links ) ) {
847 $pagination_links = $r['before'] . $pagination_links . $r['after'];
848 }
849
850 // Filter & return
851 return apply_filters( 'bbp_get_topic_pagination', $pagination_links, $args );
852 }
853
854 /**
855 * Append revisions to the topic content
856 *
857 * @since 2.0.0 bbPress (r2782)
858 *
859 * @param string $content Optional. Content to which we need to append the revisions to
860 * @param int $topic_id Optional. Topic id
861 * @return string Content with the revisions appended
862 */
863 function bbp_topic_content_append_revisions( $content = '', $topic_id = 0 ) {
864
865 // Bail if in admin or feed
866 if ( is_admin() || is_feed() ) {
867 return;
868 }
869
870 // Validate the ID
871 $topic_id = bbp_get_topic_id( $topic_id );
872
873 // Filter & return
874 return apply_filters( 'bbp_topic_append_revisions', $content . bbp_get_topic_revision_log( $topic_id ), $content, $topic_id );
875 }
876
877 /**
878 * Output the revision log of the topic
879 *
880 * @since 2.0.0 bbPress (r2782)
881 *
882 * @param int $topic_id Optional. Topic id
883 */
884 function bbp_topic_revision_log( $topic_id = 0 ) {
885 echo bbp_get_topic_revision_log( $topic_id );
886 }
887 /**
888 * Return the formatted revision log of the topic
889 *
890 * @since 2.0.0 bbPress (r2782)
891 *
892 * @param int $topic_id Optional. Topic id
893 * @return string Revision log of the topic
894 */
895 function bbp_get_topic_revision_log( $topic_id = 0 ) {
896
897 // Create necessary variables
898 $topic_id = bbp_get_topic_id( $topic_id );
899 $revision_log = bbp_get_topic_raw_revision_log( $topic_id );
900
901 if ( empty( $topic_id ) || empty( $revision_log ) || ! is_array( $revision_log ) ) {
902 return false;
903 }
904
905 $revisions = bbp_get_topic_revisions( $topic_id );
906 if ( empty( $revisions ) ) {
907 return false;
908 }
909
910 $retval = "\n\n" . '<ul id="bbp-topic-revision-log-' . esc_attr( $topic_id ) . '" class="bbp-topic-revision-log">' . "\n\n";
911
912 // Loop through revisions
913 foreach ( (array) $revisions as $revision ) {
914
915 if ( empty( $revision_log[ $revision->ID ] ) ) {
916 $author_id = $revision->post_author;
917 $reason = '';
918 } else {
919 $author_id = $revision_log[ $revision->ID ]['author'];
920 $reason = $revision_log[ $revision->ID ]['reason'];
921 }
922
923 $author = bbp_get_author_link( array( 'size' => 14, 'link_text' => bbp_get_topic_author_display_name( $revision->ID ), 'post_id' => $revision->ID ) );
924 $since = bbp_get_time_since( bbp_convert_date( $revision->post_modified ) );
925
926 $retval .= "\t" . '<li id="bbp-topic-revision-log-' . esc_attr( $topic_id ) . '-item-' . esc_attr( $revision->ID ) . '" class="bbp-topic-revision-log-item">' . "\n";
927 if ( ! empty( $reason ) ) {
928 $retval .= "\t\t" . sprintf( esc_html__( 'This topic was modified %1$s by %2$s. Reason: %3$s', 'bbpress' ), esc_html( $since ), $author, esc_html( $reason ) ) . "\n";
929 } else {
930 $retval .= "\t\t" . sprintf( esc_html__( 'This topic was modified %1$s by %2$s.', 'bbpress' ), esc_html( $since ), $author ) . "\n";
931 }
932 $retval .= "\t" . '</li>' . "\n";
933 }
934
935 $retval .= "\n" . '</ul>' . "\n\n";
936
937 // Filter & return
938 return apply_filters( 'bbp_get_topic_revision_log', $retval, $topic_id );
939 }
940 /**
941 * Return the raw revision log of the topic
942 *
943 * @since 2.0.0 bbPress (r2782)
944 *
945 * @param int $topic_id Optional. Topic id
946 * @return string Raw revision log of the topic
947 */
948 function bbp_get_topic_raw_revision_log( $topic_id = 0 ) {
949 $topic_id = bbp_get_topic_id( $topic_id );
950
951 $revision_log = get_post_meta( $topic_id, '_bbp_revision_log', true );
952 $revision_log = ! empty( $revision_log )
953 ? $revision_log
954 : array();
955
956 // Filter & return
957 return apply_filters( 'bbp_get_topic_raw_revision_log', $revision_log, $topic_id );
958 }
959
960 /**
961 * Return the revisions of the topic
962 *
963 * @since 2.0.0 bbPress (r2782)
964 *
965 * @param int $topic_id Optional. Topic id
966 * @return string Topic revisions
967 */
968 function bbp_get_topic_revisions( $topic_id = 0 ) {
969 $topic_id = bbp_get_topic_id( $topic_id );
970 $revisions = wp_get_post_revisions( $topic_id, array( 'order' => 'ASC' ) );
971
972 // Filter & return
973 return apply_filters( 'bbp_get_topic_revisions', $revisions, $topic_id );
974 }
975
976 /**
977 * Return the revision count of the topic
978 *
979 * @since 2.0.0 bbPress (r2782)
980 *
981 * @param int $topic_id Optional. Topic id
982 * @return string Topic revision count
983 */
984 function bbp_get_topic_revision_count( $topic_id = 0, $integer = false ) {
985 $topic_id = bbp_get_topic_id( $topic_id );
986 $count = count( bbp_get_topic_revisions( $topic_id ) );
987 $filter = ( true === $integer )
988 ? 'bbp_get_topic_revision_count_int'
989 : 'bbp_get_topic_revision_count';
990
991 return apply_filters( $filter, $count, $topic_id );
992 }
993
994 /**
995 * Is the topic a sticky or super sticky?
996 *
997 * @since 2.0.0 bbPress (r2754)
998 *
999 * @param int $topic_id Optional. Topic id
1000 * @param int $check_super Optional. If set to true and if the topic is not a
1001 * normal sticky, it is checked if it is a super
1002 * sticky or not. Defaults to true.
1003 * @return bool True if sticky or super sticky, false if not.
1004 */
1005 function bbp_is_topic_sticky( $topic_id = 0, $check_super = true ) {
1006 $topic_id = bbp_get_topic_id( $topic_id );
1007 $forum_id = bbp_get_topic_forum_id( $topic_id );
1008 $stickies = bbp_get_stickies( $forum_id );
1009 $retval = in_array( $topic_id, $stickies, true );
1010
1011 // Maybe check super stickies
1012 if ( ( false === $retval ) && ( true === $check_super ) ) {
1013 $retval = bbp_is_topic_super_sticky( $topic_id );
1014 }
1015
1016 // Filter & return
1017 return (bool) apply_filters( 'bbp_is_topic_sticky', $retval, $topic_id, $check_super );
1018 }
1019
1020 /**
1021 * Is the topic a super sticky?
1022 *
1023 * @since 2.0.0 bbPress (r2754)
1024 *
1025 * @param int $topic_id Optional. Topic id
1026 * @return bool True if super sticky, false if not.
1027 */
1028 function bbp_is_topic_super_sticky( $topic_id = 0 ) {
1029 $topic_id = bbp_get_topic_id( $topic_id );
1030 $stickies = bbp_get_super_stickies( $topic_id );
1031 $retval = in_array( $topic_id, $stickies, true );
1032
1033 // Filter & return
1034 return (bool) apply_filters( 'bbp_is_topic_super_sticky', $retval, $topic_id );
1035 }
1036
1037 /**
1038 * Output the status of the topic
1039 *
1040 * @since 2.0.0 bbPress (r2667)
1041 *
1042 * @param int $topic_id Optional. Topic id
1043 */
1044 function bbp_topic_status( $topic_id = 0 ) {
1045 echo bbp_get_topic_status( $topic_id );
1046 }
1047 /**
1048 * Return the status of the topic
1049 *
1050 * @since 2.0.0 bbPress (r2667)
1051 *
1052 * @param int $topic_id Optional. Topic id
1053 * @return string Status of topic
1054 */
1055 function bbp_get_topic_status( $topic_id = 0 ) {
1056 $topic_id = bbp_get_topic_id( $topic_id );
1057
1058 // Filter & return
1059 return apply_filters( 'bbp_get_topic_status', get_post_status( $topic_id ), $topic_id );
1060 }
1061
1062 /**
1063 * Is the topic closed to new replies?
1064 *
1065 * @since 2.0.0 bbPress (r2746)
1066 *
1067 * @param int $topic_id Optional. Topic id
1068 *
1069 * @return bool True if closed, false if not.
1070 */
1071 function bbp_is_topic_closed( $topic_id = 0 ) {
1072 $topic_id = bbp_get_topic_id( $topic_id );
1073 $status = bbp_get_closed_status_id();
1074 $topic_status = ( bbp_get_topic_status( $topic_id ) === $status );
1075
1076 // Filter & return
1077 return (bool) apply_filters( 'bbp_is_topic_closed', $topic_status, $topic_id );
1078 }
1079
1080 /**
1081 * Is the topic open to new replies?
1082 *
1083 * @since 2.0.0 bbPress (r2727)
1084 *
1085 * @param int $topic_id Optional. Topic id
1086 *
1087 * @return bool True if open, false if closed.
1088 */
1089 function bbp_is_topic_open( $topic_id = 0 ) {
1090 return ! bbp_is_topic_closed( $topic_id );
1091 }
1092
1093 /**
1094 * Is the topic publicly viewable?
1095 *
1096 * See bbp_get_public_topic_statuses() for public statuses.
1097 *
1098 * @since 2.6.0 bbPress (r6383)
1099 *
1100 * @param int $topic_id Optional. Topic id
1101 * @return bool True if public, false if not.
1102 */
1103 function bbp_is_topic_public( $topic_id = 0 ) {
1104 $topic_id = bbp_get_topic_id( $topic_id );
1105 $status = bbp_get_topic_status( $topic_id );
1106 $public = bbp_get_public_topic_statuses();
1107 $is_public = in_array( $status, $public, true );
1108
1109 // Filter & return
1110 return (bool) apply_filters( 'bbp_is_topic_public', $is_public, $topic_id );
1111 }
1112
1113 /**
1114 * Does the topic have a published status?
1115 *
1116 * @since 2.0.0 bbPress (r3496)
1117 *
1118 * @param int $topic_id Optional. Topic id
1119 * @return bool True if published, false if not.
1120 */
1121 function bbp_is_topic_published( $topic_id = 0 ) {
1122 $topic_id = bbp_get_topic_id( $topic_id );
1123 $status = bbp_get_public_status_id();
1124 $topic_status = ( bbp_get_topic_status( $topic_id ) === $status );
1125
1126 // Filter & return
1127 return (bool) apply_filters( 'bbp_is_topic_published', $topic_status, $topic_id );
1128 }
1129
1130 /**
1131 * Is the topic marked as spam?
1132 *
1133 * @since 2.0.0 bbPress (r2727)
1134 *
1135 * @param int $topic_id Optional. Topic id
1136 * @return bool True if spam, false if not.
1137 */
1138 function bbp_is_topic_spam( $topic_id = 0 ) {
1139 $topic_id = bbp_get_topic_id( $topic_id );
1140 $status = bbp_get_spam_status_id();
1141 $topic_status = ( bbp_get_topic_status( $topic_id ) === $status );
1142
1143 // Filter & return
1144 return (bool) apply_filters( 'bbp_is_topic_spam', $topic_status, $topic_id );
1145 }
1146
1147 /**
1148 * Is the topic trashed?
1149 *
1150 * @since 2.0.0 bbPress (r2888)
1151 *
1152 * @param int $topic_id Optional. Topic id
1153 * @return bool True if trashed, false if not.
1154 */
1155 function bbp_is_topic_trash( $topic_id = 0 ) {
1156 $topic_id = bbp_get_topic_id( $topic_id );
1157 $status = bbp_get_trash_status_id();
1158 $topic_status = ( bbp_get_topic_status( $topic_id ) === $status );
1159
1160 // Filter & return
1161 return (bool) apply_filters( 'bbp_is_topic_trash', $topic_status, $topic_id );
1162 }
1163
1164 /**
1165 * Is the topic pending?
1166 *
1167 * @since 2.6.0 bbPress (r5504)
1168 *
1169 * @param int $topic_id Optional. Topic id
1170 * @return bool True if pending, false if not.
1171 */
1172 function bbp_is_topic_pending( $topic_id = 0 ) {
1173 $topic_id = bbp_get_topic_id( $topic_id );
1174 $status = bbp_get_pending_status_id();
1175 $topic_status = ( bbp_get_topic_status( $topic_id ) === $status );
1176
1177 // Filter & return
1178 return (bool) apply_filters( 'bbp_is_topic_pending', $topic_status, $topic_id );
1179 }
1180
1181 /**
1182 * Is the topic private?
1183 *
1184 * @since 2.6.0 bbPress (r5504)
1185 *
1186 * @param int $topic_id Optional. Topic id
1187 * @return bool True if private, false if not.
1188 */
1189 function bbp_is_topic_private( $topic_id = 0 ) {
1190 $topic_id = bbp_get_topic_id( $topic_id );
1191 $status = bbp_get_private_status_id();
1192 $topic_status = ( bbp_get_topic_status( $topic_id ) === $status );
1193
1194 // Filter & return
1195 return (bool) apply_filters( 'bbp_is_topic_private', $topic_status, $topic_id );
1196 }
1197
1198 /**
1199 * Is the posted by an anonymous user?
1200 *
1201 * @since 2.0.0 bbPress (r2753)
1202 *
1203 * @param int $topic_id Optional. Topic id
1204 * @return bool True if the post is by an anonymous user, false if not.
1205 */
1206 function bbp_is_topic_anonymous( $topic_id = 0 ) {
1207 $topic_id = bbp_get_topic_id( $topic_id );
1208 $retval = false;
1209
1210 if ( ! bbp_get_topic_author_id( $topic_id ) ) {
1211 $retval = true;
1212
1213 } elseif ( get_post_meta( $topic_id, '_bbp_anonymous_name', true ) ) {
1214 $retval = true;
1215
1216 } elseif ( get_post_meta( $topic_id, '_bbp_anonymous_email', true ) ) {
1217 $retval = true;
1218 }
1219
1220 // Filter & return
1221 return (bool) apply_filters( 'bbp_is_topic_anonymous', $retval, $topic_id );
1222 }
1223
1224 /**
1225 * Deprecated. Use bbp_topic_author_display_name() instead.
1226 *
1227 * Output the author of the topic.
1228 *
1229 * @since 2.0.0 bbPress (r2590)
1230 *
1231 * @deprecated 2.5.0 bbPress (r5119)
1232 *
1233 * @param int $topic_id Optional. Topic id
1234 */
1235 function bbp_topic_author( $topic_id = 0 ) {
1236 echo bbp_get_topic_author( $topic_id );
1237 }
1238 /**
1239 * Deprecated. Use bbp_get_topic_author_display_name() instead.
1240 *
1241 * Return the author of the topic
1242 *
1243 * @since 2.0.0 bbPress (r2590)
1244 *
1245 * @deprecated 2.5.0 bbPress (r5119)
1246 *
1247 * @param int $topic_id Optional. Topic id
1248 * @return string Author of topic
1249 */
1250 function bbp_get_topic_author( $topic_id = 0 ) {
1251 $topic_id = bbp_get_topic_id( $topic_id );
1252
1253 if ( ! bbp_is_topic_anonymous( $topic_id ) ) {
1254 $author = get_the_author_meta( 'display_name', bbp_get_topic_author_id( $topic_id ) );
1255 } else {
1256 $author = get_post_meta( $topic_id, '_bbp_anonymous_name', true );
1257 }
1258
1259 // Filter & return
1260 return apply_filters( 'bbp_get_topic_author', $author, $topic_id );
1261 }
1262
1263 /**
1264 * Output the author ID of the topic
1265 *
1266 * @since 2.0.0 bbPress (r2590)
1267 *
1268 * @param int $topic_id Optional. Topic id
1269 */
1270 function bbp_topic_author_id( $topic_id = 0 ) {
1271 echo bbp_get_topic_author_id( $topic_id );
1272 }
1273 /**
1274 * Return the author ID of the topic
1275 *
1276 * @since 2.0.0 bbPress (r2590)
1277 *
1278 * @param int $topic_id Optional. Topic id
1279 * @return string Author of topic
1280 */
1281 function bbp_get_topic_author_id( $topic_id = 0 ) {
1282 $topic_id = bbp_get_topic_id( $topic_id );
1283 $author_id = get_post_field( 'post_author', $topic_id );
1284
1285 // Filter & return
1286 return (int) apply_filters( 'bbp_get_topic_author_id', (int) $author_id, $topic_id );
1287 }
1288
1289 /**
1290 * Output the author display_name of the topic
1291 *
1292 * @since 2.0.0 bbPress (r2590)
1293 *
1294 * @param int $topic_id Optional. Topic id
1295 */
1296 function bbp_topic_author_display_name( $topic_id = 0 ) {
1297 echo bbp_get_topic_author_display_name( $topic_id );
1298 }
1299 /**
1300 * Return the author display_name of the topic
1301 *
1302 * @since 2.0.0 bbPress (r2485)
1303 *
1304 * @param int $topic_id Optional. Topic id
1305 * @return string Topic's author's display name
1306 */
1307 function bbp_get_topic_author_display_name( $topic_id = 0 ) {
1308 $topic_id = bbp_get_topic_id( $topic_id );
1309
1310 // Check for anonymous user
1311 if ( ! bbp_is_topic_anonymous( $topic_id ) ) {
1312
1313 // Get the author ID
1314 $author_id = bbp_get_topic_author_id( $topic_id );
1315
1316 // Try to get a display name
1317 $author_name = get_the_author_meta( 'display_name', $author_id );
1318
1319 // Fall back to user login
1320 if ( empty( $author_name ) ) {
1321 $author_name = get_the_author_meta( 'user_login', $author_id );
1322 }
1323
1324 // User does not have an account
1325 } else {
1326 $author_name = get_post_meta( $topic_id, '_bbp_anonymous_name', true );
1327 }
1328
1329 // Fallback if nothing could be found
1330 if ( empty( $author_name ) ) {
1331 $author_name = bbp_get_fallback_display_name( $topic_id );
1332 }
1333
1334 // Encode possible UTF8 display names
1335 if ( seems_utf8( $author_name ) === false ) {
1336 $author_name = utf8_encode( $author_name );
1337 }
1338
1339 // Filter & return
1340 return apply_filters( 'bbp_get_topic_author_display_name', $author_name, $topic_id );
1341 }
1342
1343 /**
1344 * Output the author avatar of the topic
1345 *
1346 * @since 2.0.0 bbPress (r2590)
1347 *
1348 * @param int $topic_id Optional. Topic id
1349 * @param int $size Optional. Avatar size. Defaults to 40
1350 */
1351 function bbp_topic_author_avatar( $topic_id = 0, $size = 40 ) {
1352 echo bbp_get_topic_author_avatar( $topic_id, $size );
1353 }
1354 /**
1355 * Return the author avatar of the topic
1356 *
1357 * @since 2.0.0 bbPress (r2590)
1358 *
1359 * @param int $topic_id Optional. Topic id
1360 * @param int $size Optional. Avatar size. Defaults to 40
1361 * @return string Avatar of the author of the topic
1362 */
1363 function bbp_get_topic_author_avatar( $topic_id = 0, $size = 40 ) {
1364 $author_avatar = '';
1365
1366 $topic_id = bbp_get_topic_id( $topic_id );
1367 if ( ! empty( $topic_id ) ) {
1368 if ( ! bbp_is_topic_anonymous( $topic_id ) ) {
1369 $author_avatar = get_avatar( bbp_get_topic_author_id( $topic_id ), $size );
1370 } else {
1371 $author_avatar = get_avatar( get_post_meta( $topic_id, '_bbp_anonymous_email', true ), $size );
1372 }
1373 }
1374
1375 // Filter & return
1376 return apply_filters( 'bbp_get_topic_author_avatar', $author_avatar, $topic_id, $size );
1377 }
1378
1379 /**
1380 * Output the author link of the topic
1381 *
1382 * @since 2.0.0 bbPress (r2717)
1383 *
1384 * @param mixed|int $args If it is an integer, it is used as topic_id. Optional.
1385 */
1386 function bbp_topic_author_link( $args = array() ) {
1387 echo bbp_get_topic_author_link( $args );
1388 }
1389 /**
1390 * Return the author link of the topic
1391 *
1392 * @since 2.0.0 bbPress (r2717)
1393 *
1394 * @param mixed|int $args If it is an integer, it is used as topic id.
1395 * Optional.
1396 * @return string Author link of topic
1397 */
1398 function bbp_get_topic_author_link( $args = array() ) {
1399
1400 // Parse arguments against default values
1401 $r = bbp_parse_args( $args, array(
1402 'post_id' => 0,
1403 'link_title' => '',
1404 'type' => 'both',
1405 'size' => 80,
1406 'sep' => '',
1407 'show_role' => false
1408 ), 'get_topic_author_link' );
1409
1410 // Default return value
1411 $author_link = '';
1412
1413 // Used as topic_id
1414 $topic_id = is_numeric( $args )
1415 ? bbp_get_topic_id( $args )
1416 : bbp_get_topic_id( $r['post_id'] );
1417
1418 // Topic ID is good
1419 if ( ! empty( $topic_id ) ) {
1420
1421 // Get some useful topic information
1422 $author_url = bbp_get_topic_author_url( $topic_id );
1423 $anonymous = bbp_is_topic_anonymous( $topic_id );
1424
1425 // Tweak link title if empty
1426 if ( empty( $r['link_title'] ) ) {
1427 $author = bbp_get_topic_author_display_name( $topic_id );
1428 $title = empty( $anonymous )
1429 ? esc_attr__( "View %s's profile", 'bbpress' )
1430 : esc_attr__( "Visit %s's website", 'bbpress' );
1431
1432 $link_title = sprintf( $title, $author );
1433
1434 // Use what was passed if not
1435 } else {
1436 $link_title = $r['link_title'];
1437 }
1438
1439 // Setup title and author_links array
1440 $author_links = array();
1441 $link_title = ! empty( $link_title )
1442 ? ' title="' . esc_attr( $link_title ) . '"'
1443 : '';
1444
1445 // Get avatar (unescaped, because HTML)
1446 if ( ( 'avatar' === $r['type'] ) || ( 'both' === $r['type'] ) ) {
1447 $author_links['avatar'] = bbp_get_topic_author_avatar( $topic_id, $r['size'] );
1448 }
1449
1450 // Get display name (escaped, because never HTML)
1451 if ( ( 'name' === $r['type'] ) || ( 'both' === $r['type'] ) ) {
1452 $author_links['name'] = esc_html( bbp_get_topic_author_display_name( $topic_id ) );
1453 }
1454
1455 // Empty array
1456 $links = array();
1457 $sprint = '<span %1$s>%2$s</span>';
1458
1459 // Wrap each link
1460 foreach ( $author_links as $link => $link_text ) {
1461 $link_class = ' class="bbp-author-' . esc_attr( $link ) . '"';
1462 $links[] = sprintf( $sprint, $link_class, $link_text );
1463 }
1464
1465 // Juggle
1466 $author_links = $links;
1467 unset( $links );
1468
1469 // Filter sections
1470 $sections = apply_filters( 'bbp_get_topic_author_links', $author_links, $r, $args );
1471
1472 // Assemble sections into author link
1473 $author_link = implode( $r['sep'], $sections );
1474
1475 // Only wrap in link if profile exists
1476 if ( empty( $anonymous ) && bbp_user_has_profile( bbp_get_topic_author_id( $topic_id ) ) ) {
1477 $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 );
1478 }
1479
1480 // Role is not linked
1481 if ( true === $r['show_role'] ) {
1482 $author_link .= bbp_get_topic_author_role( array( 'topic_id' => $topic_id ) );
1483 }
1484 }
1485
1486 // Filter & return
1487 return apply_filters( 'bbp_get_topic_author_link', $author_link, $r, $args );
1488 }
1489
1490 /**
1491 * Output the author url of the topic
1492 *
1493 * @since 2.0.0 bbPress (r2590)
1494 *
1495 * @param int $topic_id Optional. Topic id
1496 */
1497 function bbp_topic_author_url( $topic_id = 0 ) {
1498 echo esc_url( bbp_get_topic_author_url( $topic_id ) );
1499 }
1500
1501 /**
1502 * Return the author url of the topic
1503 *
1504 * @since 2.0.0 bbPress (r2590)
1505 *
1506 * @param int $topic_id Optional. Topic id
1507 * @return string Author URL of topic
1508 */
1509 function bbp_get_topic_author_url( $topic_id = 0 ) {
1510 $topic_id = bbp_get_topic_id( $topic_id );
1511
1512 // Check for anonymous user or non-existant user
1513 if ( ! bbp_is_topic_anonymous( $topic_id ) && bbp_user_has_profile( bbp_get_topic_author_id( $topic_id ) ) ) {
1514 $author_url = bbp_get_user_profile_url( bbp_get_topic_author_id( $topic_id ) );
1515 } else {
1516 $author_url = get_post_meta( $topic_id, '_bbp_anonymous_website', true );
1517
1518 // Set empty author_url as empty string
1519 if ( empty( $author_url ) ) {
1520 $author_url = '';
1521 }
1522 }
1523
1524 // Filter & return
1525 return apply_filters( 'bbp_get_topic_author_url', $author_url, $topic_id );
1526 }
1527
1528 /**
1529 * Output the topic author email address
1530 *
1531 * @since 2.0.0 bbPress (r3445)
1532 *
1533 * @param int $topic_id Optional. Reply id
1534 */
1535 function bbp_topic_author_email( $topic_id = 0 ) {
1536 echo bbp_get_topic_author_email( $topic_id );
1537 }
1538 /**
1539 * Return the topic author email address
1540 *
1541 * @since 2.0.0 bbPress (r3445)
1542 *
1543 * @param int $topic_id Optional. Reply id
1544 * @return string Topic author email address
1545 */
1546 function bbp_get_topic_author_email( $topic_id = 0 ) {
1547 $topic_id = bbp_get_topic_id( $topic_id );
1548
1549 // Not anonymous user
1550 if ( ! bbp_is_topic_anonymous( $topic_id ) ) {
1551
1552 // Use topic author email address
1553 $user_id = bbp_get_topic_author_id( $topic_id );
1554 $user = get_userdata( $user_id );
1555 $author_email = ! empty( $user->user_email ) ? $user->user_email : '';
1556
1557 // Anonymous
1558 } else {
1559
1560 // Get email from post meta
1561 $author_email = get_post_meta( $topic_id, '_bbp_anonymous_email', true );
1562
1563 // Sanity check for missing email address
1564 if ( empty( $author_email ) ) {
1565 $author_email = '';
1566 }
1567 }
1568
1569 // Filter & return
1570 return apply_filters( 'bbp_get_topic_author_email', $author_email, $topic_id );
1571 }
1572
1573 /**
1574 * Output the topic author role
1575 *
1576 * @since 2.1.0 bbPress (r3860)
1577 *
1578 * @param array $args Optional.
1579 */
1580 function bbp_topic_author_role( $args = array() ) {
1581 echo bbp_get_topic_author_role( $args );
1582 }
1583 /**
1584 * Return the topic author role
1585 *
1586 * @since 2.1.0 bbPress (r3860)
1587 *
1588 * @param array $args Optional.
1589 * @return string topic author role
1590 */
1591 function bbp_get_topic_author_role( $args = array() ) {
1592
1593 // Parse arguments against default values
1594 $r = bbp_parse_args( $args, array(
1595 'topic_id' => 0,
1596 'class' => false,
1597 'before' => '<div class="bbp-author-role">',
1598 'after' => '</div>'
1599 ), 'get_topic_author_role' );
1600
1601 $topic_id = bbp_get_topic_id( $r['topic_id'] );
1602 $role = bbp_get_user_display_role( bbp_get_topic_author_id( $topic_id ) );
1603
1604 // Backwards compatibilty with old 'class' argument
1605 if ( ! empty( $r['class'] ) ) {
1606 $author_role = sprintf( '%1$s<div class="%2$s">%3$s</div>%4$s', $r['before'], $r['class'], $role, $r['after'] );
1607
1608 // Simpler before & after arguments
1609 // https://bbpress.trac.wordpress.org/ticket/2557
1610 } else {
1611 $author_role = $r['before'] . $role . $r['after'];
1612 }
1613
1614 // Filter & return
1615 return apply_filters( 'bbp_get_topic_author_role', $author_role, $r );
1616 }
1617
1618
1619 /**
1620 * Output the title of the forum a topic belongs to
1621 *
1622 * @since 2.0.0 bbPress (r2485)
1623 *
1624 * @param int $topic_id Optional. Topic id
1625 */
1626 function bbp_topic_forum_title( $topic_id = 0 ) {
1627 echo bbp_get_topic_forum_title( $topic_id );
1628 }
1629 /**
1630 * Return the title of the forum a topic belongs to
1631 *
1632 * @since 2.0.0 bbPress (r2485)
1633 *
1634 * @param int $topic_id Optional. Topic id
1635 * @return string Topic forum title
1636 */
1637 function bbp_get_topic_forum_title( $topic_id = 0 ) {
1638 $topic_id = bbp_get_topic_id( $topic_id );
1639 $forum_id = bbp_get_topic_forum_id( $topic_id );
1640
1641 // Filter & return
1642 return apply_filters( 'bbp_get_topic_forum', bbp_get_forum_title( $forum_id ), $topic_id, $forum_id );
1643 }
1644
1645 /**
1646 * Output the forum id a topic belongs to
1647 *
1648 * @since 2.0.0 bbPress (r2491)
1649 *
1650 * @param int $topic_id Optional. Topic id
1651 */
1652 function bbp_topic_forum_id( $topic_id = 0 ) {
1653 echo bbp_get_topic_forum_id( $topic_id );
1654 }
1655 /**
1656 * Return the forum id a topic belongs to
1657 *
1658 * @since 2.0.0 bbPress (r2491)
1659 *
1660 * @param int $topic_id Optional. Topic id
1661 * @return int Topic forum id
1662 */
1663 function bbp_get_topic_forum_id( $topic_id = 0 ) {
1664 $topic_id = bbp_get_topic_id( $topic_id );
1665 $forum_id = (int) get_post_field( 'post_parent', $topic_id );
1666
1667 // Meta-data fallback
1668 if ( empty( $forum_id ) ) {
1669 $forum_id = (int) get_post_meta( $topic_id, '_bbp_forum_id', true );
1670 }
1671
1672 // Filter
1673 if ( ! empty( $forum_id ) ) {
1674 $forum_id = (int) bbp_get_forum_id( $forum_id );
1675 }
1676
1677 // Filter & return
1678 return (int) apply_filters( 'bbp_get_topic_forum_id', $forum_id, $topic_id );
1679 }
1680
1681 /**
1682 * Output the topics last active ID
1683 *
1684 * @since 2.0.0 bbPress (r2860)
1685 *
1686 * @param int $topic_id Optional. Forum id
1687 */
1688 function bbp_topic_last_active_id( $topic_id = 0 ) {
1689 echo bbp_get_topic_last_active_id( $topic_id );
1690 }
1691 /**
1692 * Return the topics last active ID
1693 *
1694 * @since 2.0.0 bbPress (r2860)
1695 *
1696 * @param int $topic_id Optional. Forum id
1697 * @return int Forum's last active id
1698 */
1699 function bbp_get_topic_last_active_id( $topic_id = 0 ) {
1700 $topic_id = bbp_get_topic_id( $topic_id );
1701 $active_id = (int) get_post_meta( $topic_id, '_bbp_last_active_id', true );
1702
1703 // Filter & return
1704 return (int) apply_filters( 'bbp_get_topic_last_active_id', $active_id, $topic_id );
1705 }
1706
1707 /**
1708 * Output the topics last update date/time (aka freshness)
1709 *
1710 * @since 2.0.0 bbPress (r2625)
1711 *
1712 * @param int $topic_id Optional. Topic id
1713 */
1714 function bbp_topic_last_active_time( $topic_id = 0 ) {
1715 echo bbp_get_topic_last_active_time( $topic_id );
1716 }
1717 /**
1718 * Return the topics last update date/time (aka freshness)
1719 *
1720 * @since 2.0.0 bbPress (r2625)
1721 *
1722 * @param int $topic_id Optional. Topic id
1723 * @return string Topic freshness
1724 */
1725 function bbp_get_topic_last_active_time( $topic_id = 0 ) {
1726 $topic_id = bbp_get_topic_id( $topic_id );
1727
1728 // Try to get the most accurate freshness time possible
1729 $last_active = get_post_meta( $topic_id, '_bbp_last_active_time', true );
1730 if ( empty( $last_active ) ) {
1731 $reply_id = bbp_get_topic_last_reply_id( $topic_id );
1732 if ( ! empty( $reply_id ) ) {
1733 $last_active = get_post_field( 'post_date', $reply_id );
1734 } else {
1735 $last_active = get_post_field( 'post_date', $topic_id );
1736 }
1737 }
1738
1739 $last_active = ! empty( $last_active ) ? bbp_get_time_since( bbp_convert_date( $last_active ) ) : '';
1740
1741 // Filter & return
1742 return apply_filters( 'bbp_get_topic_last_active', $last_active, $topic_id );
1743 }
1744
1745 /** Topic Subscriptions *******************************************************/
1746
1747 /**
1748 * Output the topic subscription link
1749 *
1750 * @since 2.5.0 bbPress (r5156)
1751 * @since 2.6.0 bbPress (r6308) Add 'redirect_to' support
1752 */
1753 function bbp_topic_subscription_link( $args = array() ) {
1754 echo bbp_get_topic_subscription_link( $args );
1755 }
1756
1757 /**
1758 * Get the topic subscription link
1759 *
1760 * A custom wrapper for bbp_get_user_subscribe_link()
1761 *
1762 * @since 2.5.0 bbPress (r5156)
1763 * @since 2.6.0 bbPress (r6308) Add 'redirect_to' support
1764 */
1765 function bbp_get_topic_subscription_link( $args = array() ) {
1766
1767 // Defaults
1768 $retval = false;
1769 $user_id = bbp_get_current_user_id();
1770 $redirect_to = bbp_is_subscriptions()
1771 ? bbp_get_subscriptions_permalink( $user_id )
1772 : '';
1773
1774 // Parse the arguments
1775 $r = bbp_parse_args( $args, array(
1776 'user_id' => $user_id,
1777 'object_id' => bbp_get_topic_id(),
1778 'object_type' => 'post',
1779 'before' => '&nbsp;|&nbsp;',
1780 'after' => '',
1781 'subscribe' => esc_html__( 'Subscribe', 'bbpress' ),
1782 'unsubscribe' => esc_html__( 'Unsubscribe', 'bbpress' ),
1783 'redirect_to' => $redirect_to
1784 ), 'get_topic_subscribe_link' );
1785
1786 // Get the link
1787 $retval = bbp_get_user_subscribe_link( $r );
1788
1789 // Filter & return
1790 return apply_filters( 'bbp_get_topic_subscribe_link', $retval, $r, $args );
1791 }
1792
1793 /** Topic Favorites ***********************************************************/
1794
1795 /**
1796 * Output the topic favorite link
1797 *
1798 * @since 2.5.0 bbPress (r5156)
1799 * @since 2.6.0 bbPress (r6308) Add 'redirect_to' support
1800 */
1801 function bbp_topic_favorite_link( $args = array() ) {
1802 echo bbp_get_topic_favorite_link( $args );
1803 }
1804
1805 /**
1806 * Get the forum favorite link
1807 *
1808 * A custom wrapper for bbp_get_user_favorites_link()
1809 *
1810 * @since 2.5.0 bbPress (r5156)
1811 * @since 2.6.0 bbPress (r6308) Add 'redirect_to' support
1812 */
1813 function bbp_get_topic_favorite_link( $args = array() ) {
1814
1815 // No link
1816 $retval = false;
1817 $user_id = bbp_get_current_user_id();
1818 $redirect_to = bbp_is_favorites()
1819 ? bbp_get_favorites_permalink( $user_id )
1820 : '';
1821
1822 // Parse the arguments
1823 $r = bbp_parse_args( $args, array(
1824 'user_id' => $user_id,
1825 'object_id' => bbp_get_topic_id(),
1826 'object_type' => 'post',
1827 'before' => '',
1828 'after' => '',
1829 'favorite' => esc_html__( 'Favorite', 'bbpress' ),
1830 'favorited' => esc_html__( 'Unfavorite', 'bbpress' ),
1831 'redirect_to' => $redirect_to
1832 ), 'get_topic_favorite_link' );
1833
1834 // Get the link
1835 $retval = bbp_get_user_favorites_link( $r );
1836
1837 // Filter & return
1838 return apply_filters( 'bbp_get_topic_favorite_link', $retval, $r, $args );
1839 }
1840
1841 /** Topic Last Reply **********************************************************/
1842
1843 /**
1844 * Output the id of the topics last reply
1845 *
1846 * @since 2.0.0 bbPress (r2625)
1847 *
1848 * @param int $topic_id Optional. Topic id
1849 */
1850 function bbp_topic_last_reply_id( $topic_id = 0 ) {
1851 echo bbp_get_topic_last_reply_id( $topic_id );
1852 }
1853 /**
1854 * Return the id of the topics last reply
1855 *
1856 * @since 2.0.0 bbPress (r2625)
1857 *
1858 * @param int $topic_id Optional. Topic id
1859 * @return int Topic last reply id
1860 */
1861 function bbp_get_topic_last_reply_id( $topic_id = 0 ) {
1862 $topic_id = bbp_get_topic_id( $topic_id );
1863 $reply_id = (int) get_post_meta( $topic_id, '_bbp_last_reply_id', true );
1864
1865 // Filter & return
1866 return (int) apply_filters( 'bbp_get_topic_last_reply_id', $reply_id, $topic_id );
1867 }
1868
1869 /**
1870 * Output the title of the last reply inside a topic
1871 *
1872 * @since 2.0.0 bbPress (r2753)
1873 *
1874 * @param int $topic_id Optional. Topic id
1875 */
1876 function bbp_topic_last_reply_title( $topic_id = 0 ) {
1877 echo bbp_get_topic_last_reply_title( $topic_id );
1878 }
1879 /**
1880 * Return the title of the last reply inside a topic
1881 *
1882 * @since 2.0.0 bbPress (r2753)
1883 * @since 2.6.0 bbPress https://bbpress.trac.wordpress.org/ticket/3039
1884 *
1885 * @param int $topic_id Optional. Topic id
1886 * @return string Topic last reply title
1887 */
1888 function bbp_get_topic_last_reply_title( $topic_id = 0 ) {
1889 $topic_id = bbp_get_topic_id( $topic_id );
1890 $reply_id = bbp_get_topic_last_reply_id( $topic_id );
1891 $retval = bbp_get_reply_title( $reply_id );
1892
1893 // Misspelled. Use 'bbp_get_topic_last_reply_title' hook instead.
1894 $retval = apply_filters( 'bbp_get_topic_last_topic_title', $retval, $topic_id, $reply_id );
1895
1896 // Filter & return
1897 return apply_filters( 'bbp_get_topic_last_reply_title', $retval, $topic_id, $reply_id );
1898 }
1899
1900 /**
1901 * Output the link to the last reply in a topic
1902 *
1903 * @since 2.0.0 bbPress (r2464)
1904 *
1905 * @param int $topic_id Optional. Topic id
1906 */
1907 function bbp_topic_last_reply_permalink( $topic_id = 0 ) {
1908 echo esc_url( bbp_get_topic_last_reply_permalink( $topic_id ) );
1909 }
1910 /**
1911 * Return the link to the last reply in a topic
1912 *
1913 * @since 2.0.0 bbPress (r2464)
1914 *
1915 * @param int $topic_id Optional. Topic id
1916 * @return string Permanent link to the reply
1917 */
1918 function bbp_get_topic_last_reply_permalink( $topic_id = 0 ) {
1919 $topic_id = bbp_get_topic_id( $topic_id );
1920 $reply_id = bbp_get_topic_last_reply_id( $topic_id );
1921 $retval = bbp_get_reply_permalink( $reply_id );
1922
1923 // Filter & return
1924 return apply_filters( 'bbp_get_topic_last_reply_permalink', $retval, $topic_id, $reply_id );
1925 }
1926
1927 /**
1928 * Output the link to the last reply in a topic
1929 *
1930 * @since 2.0.0 bbPress (r2683)
1931 *
1932 * @param int $topic_id Optional. Topic id
1933 */
1934 function bbp_topic_last_reply_url( $topic_id = 0 ) {
1935 echo esc_url( bbp_get_topic_last_reply_url( $topic_id ) );
1936 }
1937 /**
1938 * Return the link to the last reply in a topic
1939 *
1940 * @since 2.0.0 bbPress (r2683)
1941 *
1942 * @param int $topic_id Optional. Topic id
1943 * @return string Topic last reply url
1944 */
1945 function bbp_get_topic_last_reply_url( $topic_id = 0 ) {
1946 $topic_id = bbp_get_topic_id( $topic_id );
1947 $reply_id = bbp_get_topic_last_reply_id( $topic_id );
1948
1949 if ( ! empty( $reply_id ) && ( $reply_id !== $topic_id ) ) {
1950 $reply_url = bbp_get_reply_url( $reply_id );
1951 } else {
1952 $reply_url = bbp_get_topic_permalink( $topic_id );
1953 }
1954
1955 // Filter & return
1956 return apply_filters( 'bbp_get_topic_last_reply_url', $reply_url, $topic_id, $reply_id );
1957 }
1958
1959 /**
1960 * Output link to the most recent activity inside a topic, complete with link
1961 * attributes and content.
1962 *
1963 * @since 2.0.0 bbPress (r2625)
1964 *
1965 * @param int $topic_id Optional. Topic id
1966 */
1967 function bbp_topic_freshness_link( $topic_id = 0 ) {
1968 echo bbp_get_topic_freshness_link( $topic_id );
1969 }
1970 /**
1971 * Returns link to the most recent activity inside a topic, complete
1972 * with link attributes and content.
1973 *
1974 * @since 2.0.0 bbPress (r2625)
1975 *
1976 * @param int $topic_id Optional. Topic id
1977 * @return string Topic freshness link
1978 */
1979 function bbp_get_topic_freshness_link( $topic_id = 0 ) {
1980 $topic_id = bbp_get_topic_id( $topic_id );
1981 $link_url = bbp_get_topic_last_reply_url( $topic_id );
1982 $title = bbp_get_topic_last_reply_title( $topic_id );
1983 $time_since = bbp_get_topic_last_active_time( $topic_id );
1984
1985 if ( ! empty( $time_since ) ) {
1986 $anchor = '<a href="' . esc_url( $link_url ) . '" title="' . esc_attr( $title ) . '">' . esc_html( $time_since ) . '</a>';
1987 } else {
1988 $anchor = esc_html__( 'No Replies', 'bbpress' );
1989 }
1990
1991 // Filter & return
1992 return apply_filters( 'bbp_get_topic_freshness_link', $anchor, $topic_id, $time_since, $link_url, $title );
1993 }
1994
1995 /**
1996 * Output the replies link of the topic
1997 *
1998 * @since 2.0.0 bbPress (r2740)
1999 *
2000 * @param int $topic_id Optional. Topic id
2001 */
2002 function bbp_topic_replies_link( $topic_id = 0 ) {
2003 echo bbp_get_topic_replies_link( $topic_id );
2004 }
2005
2006 /**
2007 * Return the replies link of the topic
2008 *
2009 * @since 2.0.0 bbPress (r2740)
2010 *
2011 * @param int $topic_id Optional. Topic id
2012 */
2013 function bbp_get_topic_replies_link( $topic_id = 0 ) {
2014 $topic_id = bbp_get_topic_id( $topic_id );
2015 $link = bbp_get_topic_permalink( $topic_id );
2016 $replies = sprintf( _n( '%s reply', '%s replies', bbp_get_topic_reply_count( $topic_id, true ), 'bbpress' ), bbp_get_topic_reply_count( $topic_id, false ) );
2017
2018 // First link never has view=all
2019 $retval = bbp_get_view_all( 'edit_others_replies' )
2020 ? "<a href='" . esc_url( bbp_remove_view_all( $link ) ) . "'>" . esc_html( $replies ) . "</a>"
2021 : $replies;
2022
2023 // Any deleted replies?
2024 $deleted_int = bbp_get_topic_reply_count_hidden( $topic_id, true );
2025
2026 // This topic has hidden replies
2027 if ( ! empty( $deleted_int ) && current_user_can( 'edit_others_replies' ) ) {
2028
2029 // Hidden replies
2030 $deleted_num = bbp_get_topic_reply_count_hidden( $topic_id, false );
2031 $extra = ' ' . sprintf( _n( '(+%s hidden)', '(+%s hidden)', $deleted_int, 'bbpress' ), $deleted_num );
2032
2033 // Hidden link
2034 $retval .= ! bbp_get_view_all( 'edit_others_replies' )
2035 ? " <a href='" . esc_url( bbp_add_view_all( $link, true ) ) . "'>" . esc_html( $extra ) . "</a>"
2036 : " {$extra}";
2037 }
2038
2039 // Filter & return
2040 return apply_filters( 'bbp_get_topic_replies_link', $retval, $topic_id );
2041 }
2042
2043 /**
2044 * Output total reply count of a topic
2045 *
2046 * @since 2.0.0 bbPress (r2485)
2047 *
2048 * @param int $topic_id Optional. Topic id
2049 * @param boolean $integer Optional. Whether or not to format the result
2050 */
2051 function bbp_topic_reply_count( $topic_id = 0, $integer = false ) {
2052 echo bbp_get_topic_reply_count( $topic_id, $integer );
2053 }
2054 /**
2055 * Return total reply count of a topic
2056 *
2057 * @since 2.0.0 bbPress (r2485)
2058 *
2059 * @param int $topic_id Optional. Topic id
2060 * @param boolean $integer Optional. Whether or not to format the result
2061 * @return int Reply count
2062 */
2063 function bbp_get_topic_reply_count( $topic_id = 0, $integer = false ) {
2064 $topic_id = bbp_get_topic_id( $topic_id );
2065 $replies = (int) get_post_meta( $topic_id, '_bbp_reply_count', true );
2066 $filter = ( true === $integer )
2067 ? 'bbp_get_topic_reply_count_int'
2068 : 'bbp_get_topic_reply_count';
2069
2070 return apply_filters( $filter, $replies, $topic_id );
2071 }
2072
2073 /**
2074 * Output total post count of a topic
2075 *
2076 * @since 2.0.0 bbPress (r2954)
2077 *
2078 * @param int $topic_id Optional. Topic id
2079 * @param boolean $integer Optional. Whether or not to format the result
2080 */
2081 function bbp_topic_post_count( $topic_id = 0, $integer = false ) {
2082 echo bbp_get_topic_post_count( $topic_id, $integer );
2083 }
2084 /**
2085 * Return total post count of a topic
2086 *
2087 * @since 2.0.0 bbPress (r2954)
2088 *
2089 * @param int $topic_id Optional. Topic id
2090 * @param boolean $integer Optional. Whether or not to format the result
2091 * @return int Post count
2092 */
2093 function bbp_get_topic_post_count( $topic_id = 0, $integer = false ) {
2094 $topic_id = bbp_get_topic_id( $topic_id );
2095 $replies = ( (int) get_post_meta( $topic_id, '_bbp_reply_count', true ) ) + 1;
2096 $filter = ( true === $integer )
2097 ? 'bbp_get_topic_post_count_int'
2098 : 'bbp_get_topic_post_count';
2099
2100 return apply_filters( $filter, $replies, $topic_id );
2101 }
2102
2103 /**
2104 * Output total hidden reply count of a topic (hidden includes trashed and
2105 * spammed replies)
2106 *
2107 * @since 2.0.0 bbPress (r2740)
2108 *
2109 * @param int $topic_id Optional. Topic id
2110 * @param boolean $integer Optional. Whether or not to format the result
2111 */
2112 function bbp_topic_reply_count_hidden( $topic_id = 0, $integer = false ) {
2113 echo bbp_get_topic_reply_count_hidden( $topic_id, $integer );
2114 }
2115 /**
2116 * Return total hidden reply count of a topic (hidden includes trashed
2117 * and spammed replies)
2118 *
2119 * @since 2.0.0 bbPress (r2740)
2120 *
2121 * @param int $topic_id Optional. Topic id
2122 * @param boolean $integer Optional. Whether or not to format the result
2123 * @return int Topic hidden reply count
2124 */
2125 function bbp_get_topic_reply_count_hidden( $topic_id = 0, $integer = false ) {
2126 $topic_id = bbp_get_topic_id( $topic_id );
2127 $replies = (int) get_post_meta( $topic_id, '_bbp_reply_count_hidden', true );
2128 $filter = ( true === $integer )
2129 ? 'bbp_get_topic_reply_count_hidden_int'
2130 : 'bbp_get_topic_reply_count_hidden';
2131
2132 return apply_filters( $filter, $replies, $topic_id );
2133 }
2134
2135 /**
2136 * Output total voice count of a topic
2137 *
2138 * @since 2.0.0 bbPress (r2567)
2139 *
2140 * @param int $topic_id Optional. Topic id
2141 */
2142 function bbp_topic_voice_count( $topic_id = 0, $integer = false ) {
2143 echo bbp_get_topic_voice_count( $topic_id, $integer );
2144 }
2145 /**
2146 * Return total voice count of a topic
2147 *
2148 * @since 2.0.0 bbPress (r2567)
2149 *
2150 * @param int $topic_id Optional. Topic id
2151 * @return int Voice count of the topic
2152 */
2153 function bbp_get_topic_voice_count( $topic_id = 0, $integer = false ) {
2154 $topic_id = bbp_get_topic_id( $topic_id );
2155 $voices = (int) get_post_meta( $topic_id, '_bbp_voice_count', true );
2156 $filter = ( true === $integer )
2157 ? 'bbp_get_topic_voice_count_int'
2158 : 'bbp_get_topic_voice_count';
2159
2160 return apply_filters( $filter, $voices, $topic_id );
2161 }
2162
2163 /**
2164 * Output a the tags of a topic
2165 *
2166 * @since 2.0.0 bbPress (r2688)
2167 *
2168 * @param int $topic_id Optional. Topic id
2169 * @param array $args See {@link bbp_get_topic_tag_list()}
2170 */
2171 function bbp_topic_tag_list( $topic_id = 0, $args = array() ) {
2172 echo bbp_get_topic_tag_list( $topic_id, $args );
2173 }
2174 /**
2175 * Return the tags of a topic
2176 *
2177 * @since 2.0.0 bbPress (r2688)
2178 *
2179 * @param int $topic_id Optional. Topic id
2180 * @param array $args This function supports these arguments:
2181 * - before: Before the tag list
2182 * - sep: Tag separator
2183 * - after: After the tag list
2184 * @return string Tag list of the topic
2185 */
2186 function bbp_get_topic_tag_list( $topic_id = 0, $args = array() ) {
2187
2188 // Bail if topic-tags are off
2189 if ( ! bbp_allow_topic_tags() ) {
2190 return '';
2191 }
2192
2193 // Parse arguments against default values
2194 $r = bbp_parse_args( $args, array(
2195 'before' => '<div class="bbp-topic-tags"><p>' . esc_html__( 'Tagged:', 'bbpress' ) . '&nbsp;',
2196 'sep' => ', ',
2197 'after' => '</p></div>',
2198 'none' => ''
2199 ), 'get_topic_tag_list' );
2200
2201 $topic_id = bbp_get_topic_id( $topic_id );
2202
2203 // Topic is spammed, so display pre-spam terms
2204 if ( bbp_is_topic_spam( $topic_id ) ) {
2205
2206 // Get pre-spam terms
2207 $terms = get_post_meta( $topic_id, '_bbp_spam_topic_tags', true );
2208
2209 // If terms exist, implode them and compile the return value
2210 if ( ! empty( $terms ) ) {
2211 $terms = $r['before'] . implode( $r['sep'], $terms ) . $r['after'];
2212 }
2213
2214 // Topic is not spam so display a clickable term list
2215 } else {
2216 $terms = get_the_term_list( $topic_id, bbp_get_topic_tag_tax_id(), $r['before'], $r['sep'], $r['after'] );
2217 }
2218
2219 // No terms so return none string
2220 if ( ! empty( $terms ) ) {
2221 $retval = $terms;
2222 } else {
2223 $retval = $r['none'];
2224 }
2225
2226 return $retval;
2227 }
2228
2229 /**
2230 * Output the row class of a topic
2231 *
2232 * @since 2.0.0 bbPress (r2667)
2233 *
2234 * @param int $topic_id Optional. Topic id
2235 * @param array Extra classes you can pass when calling this function
2236 */
2237 function bbp_topic_class( $topic_id = 0, $classes = array() ) {
2238 echo bbp_get_topic_class( $topic_id, $classes );
2239 }
2240 /**
2241 * Return the row class of a topic
2242 *
2243 * @since 2.0.0 bbPress (r2667)
2244 *
2245 * @param int $topic_id Optional. Topic id
2246 * @param array Extra classes you can pass when calling this function
2247 * @return string Row class of a topic
2248 */
2249 function bbp_get_topic_class( $topic_id = 0, $classes = array() ) {
2250 $bbp = bbpress();
2251 $topic_id = bbp_get_topic_id( $topic_id );
2252 $forum_id = bbp_get_topic_forum_id( $topic_id );
2253 $author_id = bbp_get_topic_author_id( $topic_id );
2254 $classes = array_filter( (array) $classes );
2255 $count = isset( $bbp->topic_query->current_post )
2256 ? (int) $bbp->topic_query->current_post
2257 : 1;
2258
2259 // Stripes
2260 $even_odd = ( $count % 2 )
2261 ? 'even'
2262 : 'odd';
2263
2264 // Forum moderator replied to topic
2265 $forum_moderator = ( bbp_is_user_forum_moderator( $author_id, $forum_id ) === $author_id )
2266 ? 'forum-mod'
2267 : '';
2268
2269 // Is this topic a sticky?
2270 $sticky = bbp_is_topic_sticky( $topic_id, false )
2271 ? 'sticky'
2272 : '';
2273
2274 // Is this topic a super-sticky?
2275 $super_sticky = bbp_is_topic_super_sticky( $topic_id )
2276 ? 'super-sticky'
2277 : '';
2278
2279 // Get topic classes
2280 $topic_classes = array(
2281 'loop-item-' . $count,
2282 'user-id-' . $author_id,
2283 'bbp-parent-forum-' . $forum_id,
2284 $even_odd,
2285 $forum_moderator,
2286 $sticky,
2287 $super_sticky
2288 );
2289
2290 // Run the topic classes through the post-class filters, which also
2291 // handles the escaping of each individual class.
2292 $post_classes = get_post_class( array_merge( $classes, $topic_classes ), $topic_id );
2293
2294 // Filter
2295 $new_classes = apply_filters( 'bbp_get_topic_class', $post_classes, $topic_id, $classes );
2296
2297 // Return
2298 return 'class="' . implode( ' ', $new_classes ) . '"';
2299 }
2300
2301 /** Topic Admin Links *********************************************************/
2302
2303 /**
2304 * Output admin links for topic
2305 *
2306 * @param array $args See {@link bbp_get_topic_admin_links()}
2307 */
2308 function bbp_topic_admin_links( $args = array() ) {
2309 echo bbp_get_topic_admin_links( $args );
2310 }
2311 /**
2312 * Return admin links for topic.
2313 *
2314 * Move topic functionality is handled by the edit topic page.
2315 *
2316 * @param array $args This function supports these arguments:
2317 * - id: Optional. Topic id
2318 * - before: Before the links
2319 * - after: After the links
2320 * - sep: Links separator
2321 * - links: Topic admin links array
2322 * @return string Topic admin links
2323 */
2324 function bbp_get_topic_admin_links( $args = array() ) {
2325
2326 // Parse arguments against default values
2327 $r = bbp_parse_args( $args, array(
2328 'id' => bbp_get_topic_id(),
2329 'before' => '<span class="bbp-admin-links">',
2330 'after' => '</span>',
2331 'sep' => ' | ',
2332 'links' => array()
2333 ), 'get_topic_admin_links' );
2334
2335 if ( empty( $r['links'] ) ) {
2336 $r['links'] = apply_filters( 'bbp_topic_admin_links', array(
2337 'edit' => bbp_get_topic_edit_link ( $r ),
2338 'merge' => bbp_get_topic_merge_link ( $r ),
2339 'close' => bbp_get_topic_close_link ( $r ),
2340 'stick' => bbp_get_topic_stick_link ( $r ),
2341 'trash' => bbp_get_topic_trash_link ( $r ),
2342 'spam' => bbp_get_topic_spam_link ( $r ),
2343 'approve' => bbp_get_topic_approve_link( $r ),
2344 'reply' => bbp_get_topic_reply_link ( $r )
2345 ), $r['id'] );
2346 }
2347
2348 // See if links need to be unset
2349 $topic_status = bbp_get_topic_status( $r['id'] );
2350 if ( in_array( $topic_status, bbp_get_non_public_topic_statuses(), true ) ) {
2351
2352 // Close link shouldn't be visible on trashed/spammed/pending topics
2353 unset( $r['links']['close'] );
2354
2355 // Spam link shouldn't be visible on trashed topics
2356 if ( bbp_get_trash_status_id() === $topic_status ) {
2357 unset( $r['links']['spam'] );
2358
2359 // Trash link shouldn't be visible on spam topics
2360 } elseif ( bbp_get_spam_status_id() === $topic_status ) {
2361 unset( $r['links']['trash'] );
2362 }
2363 }
2364
2365 // Process the admin links
2366 $links = implode( $r['sep'], array_filter( $r['links'] ) );
2367 $retval = $r['before'] . $links . $r['after'];
2368
2369 // Filter & return
2370 return apply_filters( 'bbp_get_topic_admin_links', $retval, $r, $args );
2371 }
2372
2373 /**
2374 * Output the edit link of the topic
2375 *
2376 * @since 2.0.0 bbPress (r2727)
2377 *
2378 * @param array $args See {@link bbp_get_topic_edit_link()}
2379 */
2380 function bbp_topic_edit_link( $args = array() ) {
2381 echo bbp_get_topic_edit_link( $args );
2382 }
2383
2384 /**
2385 * Return the edit link of the topic
2386 *
2387 * @since 2.0.0 bbPress (r2727)
2388 *
2389 * @param array $args This function supports these args:
2390 * - id: Optional. Topic id
2391 * - link_before: Before the link
2392 * - link_after: After the link
2393 * - edit_text: Edit text
2394 * @return string Topic edit link
2395 */
2396 function bbp_get_topic_edit_link( $args = array() ) {
2397
2398 // Parse arguments against default values
2399 $r = bbp_parse_args( $args, array(
2400 'id' => 0,
2401 'link_before' => '',
2402 'link_after' => '',
2403 'edit_text' => esc_html__( 'Edit', 'bbpress' )
2404 ), 'get_topic_edit_link' );
2405
2406 // Get the topic
2407 $topic = bbp_get_topic( $r['id'] );
2408
2409 // Bypass check if user has caps
2410 if ( ! current_user_can( 'edit_others_topics' ) ) {
2411
2412 // User cannot edit or it is past the lock time
2413 if ( empty( $topic ) || ! current_user_can( 'edit_topic', $topic->ID ) || bbp_past_edit_lock( $topic->post_date_gmt ) ) {
2414 return;
2415 }
2416 }
2417
2418 // Get uri
2419 $uri = bbp_get_topic_edit_url( $topic->ID );
2420
2421 // Bail if no uri
2422 if ( empty( $uri ) ) {
2423 return;
2424 }
2425
2426 $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" class="bbp-topic-edit-link">' . $r['edit_text'] . '</a>' . $r['link_after'];
2427
2428 // Filter & return
2429 return apply_filters( 'bbp_get_topic_edit_link', $retval, $r, $args );
2430 }
2431
2432 /**
2433 * Output URL to the topic edit page
2434 *
2435 * @since 2.0.0 bbPress (r2753)
2436 *
2437 * @param int $topic_id Optional. Topic id
2438 */
2439 function bbp_topic_edit_url( $topic_id = 0 ) {
2440 echo esc_url( bbp_get_topic_edit_url( $topic_id ) );
2441 }
2442 /**
2443 * Return URL to the topic edit page
2444 *
2445 * @since 2.0.0 bbPress (r2753)
2446 *
2447 * @param int $topic_id Optional. Topic id
2448 * @return string Topic edit url
2449 */
2450 function bbp_get_topic_edit_url( $topic_id = 0 ) {
2451
2452 $topic = bbp_get_topic( $topic_id );
2453 if ( empty( $topic ) ) {
2454 return;
2455 }
2456
2457 // Remove view=all link from edit
2458 $topic_link = bbp_remove_view_all( bbp_get_topic_permalink( $topic_id ) );
2459
2460 // Pretty permalinks, previously used `bbp_use_pretty_urls()`
2461 // https://bbpress.trac.wordpress.org/ticket/3054
2462 if ( false === strpos( $topic_link, '?' ) ) {
2463 $url = trailingslashit( $topic_link ) . bbp_get_edit_slug();
2464 $url = user_trailingslashit( $url );
2465
2466 // Unpretty permalinks
2467 } else {
2468 $url = add_query_arg( array(
2469 bbp_get_topic_post_type() => $topic->post_name,
2470 bbp_get_edit_rewrite_id() => '1'
2471 ), $topic_link );
2472 }
2473
2474 // Maybe add view=all
2475 $url = bbp_add_view_all( $url );
2476
2477 // Filter & return
2478 return apply_filters( 'bbp_get_topic_edit_url', $url, $topic_id );
2479 }
2480
2481 /**
2482 * Output the trash link of the topic
2483 *
2484 * @since 2.0.0 bbPress (r2727)
2485 *
2486 * @param array $args See {@link bbp_get_topic_trash_link()}
2487 */
2488 function bbp_topic_trash_link( $args = array() ) {
2489 echo bbp_get_topic_trash_link( $args );
2490 }
2491
2492 /**
2493 * Return the trash link of the topic
2494 *
2495 * @since 2.0.0 bbPress (r2727)
2496 *
2497 * @param array $args This function supports these args:
2498 * - id: Optional. Topic id
2499 * - link_before: Before the link
2500 * - link_after: After the link
2501 * - sep: Links separator
2502 * - trash_text: Trash text
2503 * - restore_text: Restore text
2504 * - delete_text: Delete text
2505 * @return string Topic trash link
2506 */
2507 function bbp_get_topic_trash_link( $args = array() ) {
2508
2509 // Parse arguments against default values
2510 $r = bbp_parse_args( $args, array(
2511 'id' => 0,
2512 'link_before' => '',
2513 'link_after' => '',
2514 'sep' => ' | ',
2515 'trash_text' => esc_html__( 'Trash', 'bbpress' ),
2516 'restore_text' => esc_html__( 'Restore', 'bbpress' ),
2517 'delete_text' => esc_html__( 'Delete', 'bbpress' )
2518 ), 'get_topic_trash_link' );
2519
2520 // Get topic
2521 $topic = bbp_get_topic( $r['id'] );
2522
2523 // Bail if no topic or current user cannot delete
2524 if ( empty( $topic ) || ! current_user_can( 'delete_topic', $topic->ID ) ) {
2525 return;
2526 }
2527
2528 $actions = array();
2529 $trash_days = bbp_get_trash_days( bbp_get_topic_post_type() );
2530
2531 if ( bbp_is_topic_trash( $topic->ID ) ) {
2532 $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_topic_trash', 'sub_action' => 'untrash', 'topic_id' => $topic->ID ) ), 'untrash-' . $topic->post_type . '_' . $topic->ID ) ) . '" class="bbp-topic-restore-link">' . $r['restore_text'] . '</a>';
2533 } elseif ( ! empty( $trash_days ) ) {
2534 $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_topic_trash', 'sub_action' => 'trash', 'topic_id' => $topic->ID ) ), 'trash-' . $topic->post_type . '_' . $topic->ID ) ) . '" class="bbp-topic-trash-link">' . $r['trash_text'] . '</a>';
2535 }
2536
2537 if ( bbp_is_topic_trash( $topic->ID ) || empty( $trash_days ) ) {
2538 $actions['delete'] = '<a title="' . esc_attr__( 'Delete this item permanently', 'bbpress' ) . '" href="' . esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'bbp_toggle_topic_trash', 'sub_action' => 'delete', 'topic_id' => $topic->ID ) ), 'delete-' . $topic->post_type . '_' . $topic->ID ) ) . '" onclick="return confirm(\'' . esc_js( esc_html__( 'Are you sure you want to delete that permanently?', 'bbpress' ) ) . '\' );" class="bbp-topic-delete-link">' . $r['delete_text'] . '</a>';
2539 }
2540
2541 // Process the admin links
2542 $retval = $r['link_before'] . implode( $r['sep'], $actions ) . $r['link_after'];
2543
2544 // Filter & return
2545 return apply_filters( 'bbp_get_topic_trash_link', $retval, $r, $args );
2546 }
2547
2548 /**
2549 * Output the close link of the topic
2550 *
2551 * @since 2.0.0 bbPress (r2727)
2552 *
2553 * @param array $args See {@link bbp_get_topic_close_link()}
2554 */
2555 function bbp_topic_close_link( $args = array() ) {
2556 echo bbp_get_topic_close_link( $args );
2557 }
2558
2559 /**
2560 * Return the close link of the topic
2561 *
2562 * @since 2.0.0 bbPress (r2727)
2563 *
2564 * @param array $args This function supports these args:
2565 * - id: Optional. Topic id
2566 * - link_before: Before the link
2567 * - link_after: After the link
2568 * - close_text: Close text
2569 * - open_text: Open text
2570 * @return string Topic close link
2571 */
2572 function bbp_get_topic_close_link( $args = array() ) {
2573
2574 // Parse arguments against default values
2575 $r = bbp_parse_args( $args, array(
2576 'id' => 0,
2577 'link_before' => '',
2578 'link_after' => '',
2579 'sep' => ' | ',
2580 'close_text' => esc_html_x( 'Close', 'Close the topic', 'bbpress' ),
2581 'open_text' => esc_html_x( 'Open', 'Open the topic', 'bbpress' )
2582 ), 'get_topic_close_link' );
2583
2584 // Get topic
2585 $topic = bbp_get_topic( $r['id'] );
2586
2587 // Bail if no topic or current user cannot moderate
2588 if ( empty( $topic ) || ! current_user_can( 'moderate', $topic->ID ) ) {
2589 return;
2590 }
2591
2592 $display = bbp_is_topic_open( $topic->ID ) ? $r['close_text'] : $r['open_text'];
2593 $uri = add_query_arg( array( 'action' => 'bbp_toggle_topic_close', 'topic_id' => $topic->ID ) );
2594 $uri = wp_nonce_url( $uri, 'close-topic_' . $topic->ID );
2595 $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" class="bbp-topic-close-link">' . $display . '</a>' . $r['link_after'];
2596
2597 // Filter & return
2598 return apply_filters( 'bbp_get_topic_close_link', $retval, $r, $args );
2599 }
2600
2601 /**
2602 * Output the approve link of the topic
2603 *
2604 * @since 2.6.0 bbPress (r5504)
2605 *
2606 * @param array $args See {@link bbp_get_topic_approve_link()}
2607 */
2608 function bbp_topic_approve_link( $args = array() ) {
2609 echo bbp_get_topic_approve_link( $args );
2610 }
2611
2612 /**
2613 * Return the approve link of the topic
2614 *
2615 * @since 2.6.0 bbPress (r5504)
2616 *
2617 * @param array $args This function supports these args:
2618 * - id: Optional. Topic id
2619 * - link_before: Before the link
2620 * - link_after: After the link
2621 * - sep: Separator between links
2622 * - approve_text: Approve text
2623 * - unapprove_text: Unapprove text
2624 * @return string Topic approve link
2625 */
2626 function bbp_get_topic_approve_link( $args = array() ) {
2627
2628 // Parse arguments against default values
2629 $r = bbp_parse_args( $args, array(
2630 'id' => 0,
2631 'link_before' => '',
2632 'link_after' => '',
2633 'sep' => ' | ',
2634 'approve_text' => esc_html_x( 'Approve', 'Approve the topic', 'bbpress' ),
2635 'unapprove_text' => esc_html_x( 'Unapprove', 'Unapprove the topic', 'bbpress' )
2636 ), 'get_topic_approve_link' );
2637
2638 // Get topic
2639 $topic = bbp_get_topic( $r['id'] );
2640
2641 // Bail if no topic or current user cannot moderate
2642 if ( empty( $topic ) || ! current_user_can( 'moderate', $topic->ID ) ) {
2643 return;
2644 }
2645
2646 $display = bbp_is_topic_pending( $topic->ID ) ? $r['approve_text'] : $r['unapprove_text'];
2647 $uri = add_query_arg( array( 'action' => 'bbp_toggle_topic_approve', 'topic_id' => $topic->ID ) );
2648 $uri = wp_nonce_url( $uri, 'approve-topic_' . $topic->ID );
2649 $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" class="bbp-topic-approve-link">' . $display . '</a>' . $r['link_after'];
2650
2651 // Filter & return
2652 return apply_filters( 'bbp_get_topic_approve_link', $retval, $r, $args );
2653 }
2654
2655 /**
2656 * Output the stick link of the topic
2657 *
2658 * @since 2.0.0 bbPress (r2754)
2659 *
2660 * @param array $args See {@link bbp_get_topic_stick_link()}
2661 */
2662 function bbp_topic_stick_link( $args = array() ) {
2663 echo bbp_get_topic_stick_link( $args );
2664 }
2665
2666 /**
2667 * Return the stick link of the topic
2668 *
2669 * @since 2.0.0 bbPress (r2754)
2670 *
2671 * @param array $args This function supports these args:
2672 * - id: Optional. Topic id
2673 * - link_before: Before the link
2674 * - link_after: After the link
2675 * - stick_text: Stick text
2676 * - unstick_text: Unstick text
2677 * - super_text: Stick to front text
2678 *
2679 * @return string Topic stick link
2680 */
2681 function bbp_get_topic_stick_link( $args = array() ) {
2682
2683 // Parse arguments against default values
2684 $r = bbp_parse_args( $args, array(
2685 'id' => 0,
2686 'link_before' => '',
2687 'link_after' => '',
2688 'stick_text' => esc_html__( 'Stick', 'bbpress' ),
2689 'unstick_text' => esc_html__( 'Unstick', 'bbpress' ),
2690 'super_text' => esc_html__( '(to front)', 'bbpress' ),
2691 ), 'get_topic_stick_link' );
2692
2693 // Get topic
2694 $topic = bbp_get_topic( $r['id'] );
2695
2696 // Bail if no topic or current user cannot moderate
2697 if ( empty( $topic ) || ! current_user_can( 'moderate', $topic->ID ) ) {
2698 return;
2699 }
2700
2701 $is_sticky = bbp_is_topic_sticky( $topic->ID );
2702
2703 $stick_uri = add_query_arg( array( 'action' => 'bbp_toggle_topic_stick', 'topic_id' => $topic->ID ) );
2704 $stick_uri = wp_nonce_url( $stick_uri, 'stick-topic_' . $topic->ID );
2705
2706 $stick_display = ( true === $is_sticky ) ? $r['unstick_text'] : $r['stick_text'];
2707 $stick_display = '<a href="' . esc_url( $stick_uri ) . '" class="bbp-topic-sticky-link">' . $stick_display . '</a>';
2708
2709 if ( empty( $is_sticky ) ) {
2710 $super_uri = add_query_arg( array( 'action' => 'bbp_toggle_topic_stick', 'topic_id' => $topic->ID, 'super' => 1 ) );
2711 $super_uri = wp_nonce_url( $super_uri, 'stick-topic_' . $topic->ID );
2712
2713 $super_display = ' <a href="' . esc_url( $super_uri ) . '" class="bbp-topic-super-sticky-link">' . $r['super_text'] . '</a>';
2714 } else {
2715 $super_display = '';
2716 }
2717
2718 // Combine the HTML into 1 string
2719 $retval = $r['link_before'] . $stick_display . $super_display . $r['link_after'];
2720
2721 // Filter & return
2722 return apply_filters( 'bbp_get_topic_stick_link', $retval, $r, $args );
2723 }
2724
2725 /**
2726 * Output the merge link of the topic
2727 *
2728 * @since 2.0.0 bbPress (r2756)
2729 *
2730 * @param array $args
2731 */
2732 function bbp_topic_merge_link( $args = array() ) {
2733 echo bbp_get_topic_merge_link( $args );
2734 }
2735
2736 /**
2737 * Return the merge link of the topic
2738 *
2739 * @since 2.0.0 bbPress (r2756)
2740 *
2741 * @param array $args This function supports these args:
2742 * - id: Optional. Topic id
2743 * - link_before: Before the link
2744 * - link_after: After the link
2745 * - merge_text: Merge text
2746 *
2747 * @return string Topic merge link
2748 */
2749 function bbp_get_topic_merge_link( $args = array() ) {
2750
2751 // Parse arguments against default values
2752 $r = bbp_parse_args( $args, array(
2753 'id' => 0,
2754 'link_before' => '',
2755 'link_after' => '',
2756 'merge_text' => esc_html__( 'Merge', 'bbpress' ),
2757 ), 'get_topic_merge_link' );
2758
2759 // Get topic
2760 $topic = bbp_get_topic( $r['id'] );
2761
2762 // Bail if no topic or current user cannot moderate
2763 if ( empty( $topic ) || ! current_user_can( 'moderate', $topic->ID ) ) {
2764 return;
2765 }
2766
2767 $uri = add_query_arg( array( 'action' => 'merge' ), bbp_get_topic_edit_url( $topic->ID ) );
2768 $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" class="bbp-topic-merge-link">' . $r['merge_text'] . '</a>' . $r['link_after'];
2769
2770 // Filter & return
2771 return apply_filters( 'bbp_get_topic_merge_link', $retval, $r, $args );
2772 }
2773
2774 /**
2775 * Output the spam link of the topic
2776 *
2777 * @since 2.0.0 bbPress (r2727)
2778 *
2779 * @param array $args See {@link bbp_get_topic_spam_link()}
2780 */
2781 function bbp_topic_spam_link( $args = array() ) {
2782 echo bbp_get_topic_spam_link( $args );
2783 }
2784
2785 /**
2786 * Return the spam link of the topic
2787 *
2788 * @since 2.0.0 bbPress (r2727)
2789 *
2790 * @param array $args This function supports these args:
2791 * - id: Optional. Topic id
2792 * - link_before: Before the link
2793 * - link_after: After the link
2794 * - spam_text: Spam text
2795 * - unspam_text: Unspam text
2796 *
2797 * @return string Topic spam link
2798 */
2799 function bbp_get_topic_spam_link( $args = array() ) {
2800
2801 // Parse arguments against default values
2802 $r = bbp_parse_args( $args, array(
2803 'id' => 0,
2804 'link_before' => '',
2805 'link_after' => '',
2806 'sep' => ' | ',
2807 'spam_text' => esc_html__( 'Spam', 'bbpress' ),
2808 'unspam_text' => esc_html__( 'Unspam', 'bbpress' )
2809 ), 'get_topic_spam_link' );
2810
2811 $topic = bbp_get_topic( $r['id'] );
2812
2813 if ( empty( $topic ) || ! current_user_can( 'moderate', $topic->ID ) ) {
2814 return;
2815 }
2816
2817 $display = bbp_is_topic_spam( $topic->ID ) ? $r['unspam_text'] : $r['spam_text'];
2818 $uri = add_query_arg( array( 'action' => 'bbp_toggle_topic_spam', 'topic_id' => $topic->ID ) );
2819 $uri = wp_nonce_url( $uri, 'spam-topic_' . $topic->ID );
2820 $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" class="bbp-topic-spam-link">' . $display . '</a>' . $r['link_after'];
2821
2822 // Filter & return
2823 return apply_filters( 'bbp_get_topic_spam_link', $retval, $r, $args );
2824 }
2825
2826 /**
2827 * Output the link to go directly to the reply form
2828 *
2829 * @since 2.4.0 bbPress (r4966)
2830 *
2831 * @param array $args
2832 */
2833 function bbp_topic_reply_link( $args = array() ) {
2834 echo bbp_get_topic_reply_link( $args );
2835 }
2836
2837 /**
2838 * Return the link to go directly to the reply form
2839 *
2840 * @since 2.4.0 bbPress (r4966)
2841 *
2842 * @param array $args Arguments
2843 *
2844 * @return string Link for a reply to a topic
2845 */
2846 function bbp_get_topic_reply_link( $args = array() ) {
2847
2848 // Parse arguments against default values
2849 $r = bbp_parse_args( $args, array(
2850 'id' => 0,
2851 'link_before' => '',
2852 'link_after' => '',
2853 'reply_text' => esc_html_x( 'Reply', 'verb', 'bbpress' ),
2854 'add_below' => 'post',
2855 'respond_id' => 'new-reply-' . bbp_get_topic_id(),
2856 ), 'get_topic_reply_link' );
2857
2858 // Get the topic to use it's ID and post_parent
2859 $topic = bbp_get_topic( $r['id'] );
2860
2861 // Bail if no topic or user cannot reply
2862 if ( empty( $topic ) || bbp_is_single_reply() || ! bbp_current_user_can_access_create_reply_form() ) {
2863 return;
2864 }
2865
2866 // Only add onclick if replies are threaded
2867 $onclick = bbp_thread_replies()
2868 ? ' onclick="return addReply.cancelForm();"'
2869 : '';
2870
2871 // Add $uri to the array, to be passed through the filter
2872 $r['uri'] = remove_query_arg( array( 'bbp_reply_to', '_wpnonce' ) ) . '#new-post';
2873 $retval = $r['link_before'] . '<a role="button" href="' . esc_url( $r['uri'] ) . '" class="bbp-topic-reply-link"' . $onclick . '>' . $r['reply_text'] . '</a>' . $r['link_after'];
2874
2875 // Filter & return
2876 return apply_filters( 'bbp_get_topic_reply_link', $retval, $r, $args );
2877 }
2878
2879 /** Topic Pagination **********************************************************/
2880
2881 /**
2882 * Return the base URL used inside of pagination links
2883 *
2884 * @since 2.6.0 bbPress (r6402)
2885 *
2886 * @param int $forum_id
2887 * @return string
2888 */
2889 function bbp_get_topics_pagination_base( $forum_id = 0 ) {
2890
2891 // If pretty permalinks are enabled, make our pagination pretty
2892 if ( bbp_use_pretty_urls() ) {
2893
2894 // User's topics
2895 if ( bbp_is_single_user_topics() ) {
2896 $base = bbp_get_user_topics_created_url( bbp_get_displayed_user_id() );
2897
2898 // User's engagements
2899 } elseif ( bbp_is_single_user_engagements() ) {
2900 $base = bbp_get_user_engagements_url( bbp_get_displayed_user_id() );
2901
2902 // User's favorites
2903 } elseif ( bbp_is_favorites() ) {
2904 $base = bbp_get_favorites_permalink( bbp_get_displayed_user_id() );
2905
2906 // User's subscriptions
2907 } elseif ( bbp_is_subscriptions() ) {
2908 $base = bbp_get_subscriptions_permalink( bbp_get_displayed_user_id() );
2909
2910 // Root profile page
2911 } elseif ( bbp_is_single_user() ) {
2912 $base = bbp_get_user_profile_url( bbp_get_displayed_user_id() );
2913
2914 // View
2915 } elseif ( bbp_is_single_view() ) {
2916 $base = bbp_get_view_url();
2917
2918 // Topic tag
2919 } elseif ( bbp_is_topic_tag() ) {
2920 $base = bbp_get_topic_tag_link();
2921
2922 // Page or single post
2923 } elseif ( is_page() || is_single() ) {
2924 $base = get_permalink();
2925
2926 // Forum archive
2927 } elseif ( bbp_is_forum_archive() ) {
2928 $base = bbp_get_forums_url();
2929
2930 // Topic archive
2931 } elseif ( bbp_is_topic_archive() ) {
2932 $base = bbp_get_topics_url();
2933
2934 // Default
2935 } else {
2936 $base = get_permalink( $forum_id );
2937 }
2938
2939 // Use pagination base
2940 $base = trailingslashit( $base ) . user_trailingslashit( bbp_get_paged_slug() . '/%#%/' );
2941
2942 // Unpretty pagination
2943 } else {
2944 $base = add_query_arg( 'paged', '%#%' );
2945 }
2946
2947 // Filter & return
2948 return apply_filters( 'bbp_get_topics_pagination_base', $base, $forum_id );
2949 }
2950
2951 /**
2952 * Output the pagination count
2953 *
2954 * The results are unescaped by design, to allow them to be filtered freely via
2955 * the 'bbp_get_forum_pagination_count' filter.
2956 *
2957 * @since 2.0.0 bbPress (r2519)
2958 */
2959 function bbp_forum_pagination_count() {
2960 echo bbp_get_forum_pagination_count();
2961 }
2962 /**
2963 * Return the pagination count
2964 *
2965 * @since 2.0.0 bbPress (r2519)
2966 *
2967 * @return string Forum Pagination count
2968 */
2969 function bbp_get_forum_pagination_count() {
2970 $bbp = bbpress();
2971
2972 // Define local variable(s)
2973 $retstr = '';
2974
2975 // Topic query exists
2976 if ( ! empty( $bbp->topic_query ) ) {
2977
2978 // Set pagination values
2979 $count_int = intval( $bbp->topic_query->post_count );
2980 $start_num = intval( ( $bbp->topic_query->paged - 1 ) * $bbp->topic_query->posts_per_page ) + 1;
2981 $total_int = ! empty( $bbp->topic_query->found_posts )
2982 ? (int) $bbp->topic_query->found_posts
2983 : $count_int;
2984
2985 // Format numbers for display
2986 $count_num = bbp_number_format( $count_int );
2987 $from_num = bbp_number_format( $start_num );
2988 $total = bbp_number_format( $total_int );
2989 $to_num = bbp_number_format( ( $start_num + ( $bbp->topic_query->posts_per_page - 1 ) > $bbp->topic_query->found_posts )
2990 ? $bbp->topic_query->found_posts
2991 : $start_num + ( $bbp->topic_query->posts_per_page - 1 ) );
2992
2993 // Several topics in a forum with a single page
2994 if ( empty( $to_num ) ) {
2995 $retstr = sprintf( _n( 'Viewing %1$s topic', 'Viewing %1$s topics', $total_int, 'bbpress' ), $total );
2996
2997 // Several topics in a forum with several pages
2998 } else {
2999 $retstr = sprintf( _n( 'Viewing topic %2$s (of %4$s total)', 'Viewing %1$s topics - %2$s through %3$s (of %4$s total)', $total_int, 'bbpress' ), $count_num, $from_num, $to_num, $total );
3000 }
3001
3002 // Escape results of _n()
3003 $retstr = esc_html( $retstr );
3004 }
3005
3006 // Filter & return
3007 return apply_filters( 'bbp_get_forum_pagination_count', $retstr );
3008 }
3009
3010 /**
3011 * Output pagination links
3012 *
3013 * @since 2.0.0 bbPress (r2519)
3014 */
3015 function bbp_forum_pagination_links() {
3016 echo bbp_get_forum_pagination_links();
3017 }
3018 /**
3019 * Return pagination links
3020 *
3021 * @since 2.0.0 bbPress (r2519)
3022 *
3023 * @return string Pagination links
3024 */
3025 function bbp_get_forum_pagination_links() {
3026 $bbp = bbpress();
3027
3028 if ( empty( $bbp->topic_query ) ) {
3029 return false;
3030 }
3031
3032 // Filter & return
3033 return apply_filters( 'bbp_get_forum_pagination_links', $bbp->topic_query->pagination_links );
3034 }
3035
3036 /**
3037 * Displays topic notices
3038 *
3039 * @since 2.0.0 bbPress (r2744)
3040 */
3041 function bbp_topic_notices() {
3042
3043 // Bail if not viewing a topic
3044 if ( ! bbp_is_single_topic() ) {
3045 return;
3046 }
3047
3048 // Get the topic_status
3049 $topic_status = bbp_get_topic_status();
3050
3051 // Get the topic status
3052 switch ( $topic_status ) {
3053
3054 // Spam notice
3055 case bbp_get_spam_status_id() :
3056 $notice_text = esc_html__( 'This topic is marked as spam.', 'bbpress' );
3057 break;
3058
3059 // Trashed notice
3060 case bbp_get_trash_status_id() :
3061 $notice_text = esc_html__( 'This topic is in the trash.', 'bbpress' );
3062 break;
3063
3064 // Pending notice
3065 case bbp_get_pending_status_id() :
3066 $notice_text = esc_html__( 'This topic is pending moderation.', 'bbpress' );
3067 break;
3068
3069 // Standard status
3070 default :
3071 $notice_text = '';
3072 break;
3073 }
3074
3075 // Filter notice text and bail if empty
3076 $notice_text = apply_filters( 'bbp_topic_notices', $notice_text, $topic_status, bbp_get_topic_id() );
3077 if ( empty( $notice_text ) ) {
3078 return;
3079 }
3080
3081 bbp_add_error( 'topic_notice', $notice_text, 'message' );
3082 }
3083
3084 /**
3085 * Displays topic type select box (normal/sticky/super sticky)
3086 *
3087 * @since 2.0.0 bbPress (r2784)
3088 *
3089 * @deprecated 2.4.0 bbPress (r5059)
3090 *
3091 * @param $args This function supports these arguments:
3092 * - select_id: Select id. Defaults to bbp_stick_topic
3093 * - tab: Deprecated. Tabindex
3094 * - topic_id: Topic id
3095 * - selected: Override the selected option
3096 */
3097 function bbp_topic_type_select( $args = array() ) {
3098 echo bbp_get_form_topic_type_dropdown( $args );
3099 }
3100
3101 /**
3102 * Displays topic type select box (normal/sticky/super sticky)
3103 *
3104 * @since 2.4.0 bbPress (r5059)
3105 *
3106 * @param $args This function supports these arguments:
3107 * - select_id: Select id. Defaults to bbp_stick_topic
3108 * - tab: Deprecated. Tabindex
3109 * - topic_id: Topic id
3110 * - selected: Override the selected option
3111 */
3112 function bbp_form_topic_type_dropdown( $args = array() ) {
3113 echo bbp_get_form_topic_type_dropdown( $args );
3114 }
3115 /**
3116 * Returns topic type select box (normal/sticky/super sticky)
3117 *
3118 * @since 2.4.0 bbPress (r5059)
3119 *
3120 * @param $args This function supports these arguments:
3121 * - select_id: Select id. Defaults to bbp_stick_topic
3122 * - tab: Deprecated. Tabindex
3123 * - topic_id: Topic id
3124 * - selected: Override the selected option
3125 */
3126 function bbp_get_form_topic_type_dropdown( $args = array() ) {
3127
3128 // Parse arguments against default values
3129 $r = bbp_parse_args( $args, array(
3130 'select_id' => 'bbp_stick_topic',
3131 'select_class' => 'bbp_dropdown',
3132 'tab' => false,
3133 'topic_id' => 0,
3134 'selected' => false
3135 ), 'topic_type_select' );
3136
3137 // No specific selected value passed
3138 if ( empty( $r['selected'] ) ) {
3139
3140 // Post value is passed
3141 if ( bbp_is_topic_form_post_request() && isset( $_POST[ $r['select_id'] ] ) ) {
3142 $r['selected'] = sanitize_key( $_POST[ $r['select_id'] ] );
3143
3144 // No Post value passed
3145 } else {
3146
3147 // Edit topic
3148 if ( bbp_is_single_topic() || bbp_is_topic_edit() ) {
3149
3150 // Get current topic id
3151 $r['topic_id'] = bbp_get_topic_id( $r['topic_id'] );
3152
3153 // Topic is super sticky
3154 if ( bbp_is_topic_super_sticky( $r['topic_id'] ) ) {
3155 $r['selected'] = 'super';
3156
3157 // Topic is sticky or normal
3158 } else {
3159 $r['selected'] = bbp_is_topic_sticky( $r['topic_id'], false )
3160 ? 'stick'
3161 : 'unstick';
3162 }
3163 }
3164 }
3165 }
3166
3167 // Start an output buffer, we'll finish it after the select loop
3168 ob_start(); ?>
3169
3170 <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'] ); ?>>
3171
3172 <?php foreach ( bbp_get_topic_types( $r['topic_id'] ) as $key => $label ) : ?>
3173
3174 <option value="<?php echo esc_attr( $key ); ?>"<?php selected( $key, $r['selected'] ); ?>><?php echo esc_html( $label ); ?></option>
3175
3176 <?php endforeach; ?>
3177
3178 </select>
3179
3180 <?php
3181
3182 // Filter & return
3183 return apply_filters( 'bbp_get_form_topic_type_dropdown', ob_get_clean(), $r, $args );
3184 }
3185
3186 /**
3187 * Output value topic status dropdown
3188 *
3189 * @since 2.4.0 bbPress (r5059)
3190 *
3191 * @param $args This function supports these arguments:
3192 * - select_id: Select id. Defaults to bbp_topic_status
3193 * - tab: Deprecated. Tabindex
3194 * - topic_id: Topic id
3195 * - selected: Override the selected option
3196 */
3197 function bbp_form_topic_status_dropdown( $args = array() ) {
3198 echo bbp_get_form_topic_status_dropdown( $args );
3199 }
3200 /**
3201 * Returns topic status dropdown
3202 *
3203 * This dropdown is only intended to be seen by users with the 'moderate'
3204 * capability. Because of this, no additional capability checks are performed
3205 * within this function to check available topic statuses.
3206 *
3207 * @since 2.4.0 bbPress (r5059)
3208 *
3209 * @param $args This function supports these arguments:
3210 * - select_id: Select id. Defaults to bbp_topic_status
3211 * - tab: Deprecated. Tabindex
3212 * - topic_id: Topic id
3213 * - selected: Override the selected option
3214 */
3215 function bbp_get_form_topic_status_dropdown( $args = array() ) {
3216
3217 // Parse arguments against default values
3218 $r = bbp_parse_args( $args, array(
3219 'select_id' => 'bbp_topic_status',
3220 'select_class' => 'bbp_dropdown',
3221 'tab' => false,
3222 'topic_id' => 0,
3223 'selected' => false
3224 ), 'topic_open_close_select' );
3225
3226 // No specific selected value passed
3227 if ( empty( $r['selected'] ) ) {
3228
3229 // Post value is passed
3230 if ( bbp_is_topic_form_post_request() && isset( $_POST[ $r['select_id'] ] ) ) {
3231 $r['selected'] = sanitize_key( $_POST[ $r['select_id'] ] );
3232
3233 // No Post value was passed
3234 } else {
3235
3236 // Edit topic
3237 if ( bbp_is_topic_edit() ) {
3238 $r['topic_id'] = bbp_get_topic_id( $r['topic_id'] );
3239 $r['selected'] = bbp_get_topic_status( $r['topic_id'] );
3240
3241 // New topic
3242 } else {
3243 $r['selected'] = bbp_get_public_status_id();
3244 }
3245 }
3246 }
3247
3248 // Start an output buffer, we'll finish it after the select loop
3249 ob_start(); ?>
3250
3251 <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'] ); ?>>
3252
3253 <?php foreach ( bbp_get_topic_statuses( $r['topic_id'] ) as $key => $label ) : ?>
3254
3255 <option value="<?php echo esc_attr( $key ); ?>"<?php selected( $key, $r['selected'] ); ?>><?php echo esc_html( $label ); ?></option>
3256
3257 <?php endforeach; ?>
3258
3259 </select>
3260
3261 <?php
3262
3263 // Filter & return
3264 return apply_filters( 'bbp_get_form_topic_status_dropdown', ob_get_clean(), $r, $args );
3265 }
3266
3267 /** Single Topic **************************************************************/
3268
3269 /**
3270 * Output a fancy description of the current topic, including total topics,
3271 * total replies, and last activity.
3272 *
3273 * @since 2.0.0 bbPress (r2860)
3274 *
3275 * @param array $args See {@link bbp_get_single_topic_description()}
3276 */
3277 function bbp_single_topic_description( $args = array() ) {
3278 echo bbp_get_single_topic_description( $args );
3279 }
3280 /**
3281 * Return a fancy description of the current topic, including total topics,
3282 * total replies, and last activity.
3283 *
3284 * @since 2.0.0 bbPress (r2860)
3285 *
3286 * @param array $args This function supports these arguments:
3287 * - topic_id: Topic id
3288 * - before: Before the text
3289 * - after: After the text
3290 * - size: Size of the avatar
3291 * @return string Filtered topic description
3292 */
3293 function bbp_get_single_topic_description( $args = array() ) {
3294
3295 // Parse arguments against default values
3296 $r = bbp_parse_args( $args, array(
3297 'topic_id' => 0,
3298 'before' => '<div class="bbp-template-notice info"><ul><li class="bbp-topic-description">',
3299 'after' => '</li></ul></div>',
3300 'size' => 14
3301 ), 'get_single_topic_description' );
3302
3303 // Validate topic_id
3304 $topic_id = bbp_get_topic_id( $r['topic_id'] );
3305
3306 // Unhook the 'view all' query var adder
3307 remove_filter( 'bbp_get_topic_permalink', 'bbp_add_view_all' );
3308
3309 // Build the topic description
3310 $vc_int = bbp_get_topic_voice_count ( $topic_id, true );
3311 $voice_count = bbp_get_topic_voice_count ( $topic_id, false );
3312 $reply_count = bbp_get_topic_replies_link ( $topic_id );
3313 $time_since = bbp_get_topic_freshness_link( $topic_id );
3314
3315 // Singular/Plural
3316 $voice_count = sprintf( _n( '%s voice', '%s voices', $vc_int, 'bbpress' ), $voice_count );
3317
3318 // Topic has activity (could be from reply or topic author)
3319 $last_active = bbp_get_topic_last_active_id( $topic_id );
3320 if ( ! empty( $vc_int ) && ! empty( $last_active ) ) {
3321 $last_updated_by = bbp_get_author_link( array( 'post_id' => $last_active, 'size' => $r['size'] ) );
3322 $retstr = sprintf( esc_html__( 'This topic has %1$s, %2$s, and was last updated %3$s by %4$s.', 'bbpress' ), $reply_count, $voice_count, $time_since, $last_updated_by );
3323
3324 // Topic has no replies
3325 } elseif ( ! empty( $vc_int ) && ! empty( $reply_count ) ) {
3326 $retstr = sprintf( esc_html__( 'This topic has %1$s and %2$s.', 'bbpress' ), $voice_count, $reply_count );
3327
3328 // Topic has no replies and no voices
3329 } elseif ( empty( $vc_int ) && empty( $reply_count ) ) {
3330 $retstr = esc_html__( 'This topic has no replies.', 'bbpress' );
3331
3332 // Topic is pending
3333 } elseif ( bbp_get_topic_status( $topic_id ) === bbp_get_pending_status_id() ) {
3334 $retstr = esc_html__( 'This topic is pending moderation.', 'bbpress' );
3335
3336 // Fallback
3337 } else {
3338 $retstr = esc_html__( 'This topic is empty.', 'bbpress' );
3339 }
3340
3341 // Add the 'view all' filter back
3342 add_filter( 'bbp_get_topic_permalink', 'bbp_add_view_all' );
3343
3344 // Combine the elements together
3345 $retstr = $r['before'] . $retstr . $r['after'];
3346
3347 // Filter & return
3348 return apply_filters( 'bbp_get_single_topic_description', $retstr, $r, $args );
3349 }
3350
3351 /** Topic Tags ****************************************************************/
3352
3353 /**
3354 * Output the unique id of the topic tag taxonomy
3355 *
3356 * @since 2.0.0 bbPress (r3348)
3357 */
3358 function bbp_topic_tag_tax_id() {
3359 echo bbp_get_topic_tag_tax_id();
3360 }
3361 /**
3362 * Return the unique id of the topic tag taxonomy
3363 *
3364 * @since 2.0.0 bbPress (r3348)
3365 *
3366 * @return string The unique topic tag taxonomy
3367 */
3368 function bbp_get_topic_tag_tax_id() {
3369
3370 // Filter & return
3371 return apply_filters( 'bbp_get_topic_tag_tax_id', bbpress()->topic_tag_tax_id );
3372 }
3373
3374 /**
3375 * Return array of labels used by the topic-tag taxonomy
3376 *
3377 * @since 2.5.0 bbPress (r5129)
3378 *
3379 * @return array
3380 */
3381 function bbp_get_topic_tag_tax_labels() {
3382
3383 // Filter & return
3384 return (array) apply_filters( 'bbp_get_topic_tag_tax_labels', array(
3385 'name' => esc_attr__( 'Topic Tags', 'bbpress' ),
3386 'menu_name' => esc_attr__( 'Topic Tags', 'bbpress' ),
3387 'singular_name' => esc_attr__( 'Topic Tag', 'bbpress' ),
3388 'search_items' => esc_attr__( 'Search Tags', 'bbpress' ),
3389 'popular_items' => esc_attr__( 'Popular Tags', 'bbpress' ),
3390 'all_items' => esc_attr__( 'All Tags', 'bbpress' ),
3391 'parent_item' => esc_attr__( 'Parent Tag', 'bbpress' ),
3392 'parent_item_colon' => esc_attr__( 'Parent Tag:', 'bbpress' ),
3393 'edit_item' => esc_attr__( 'Edit Tag', 'bbpress' ),
3394 'view_item' => esc_attr__( 'View Topic Tag', 'bbpress' ),
3395 'update_item' => esc_attr__( 'Update Tag', 'bbpress' ),
3396 'add_new_item' => esc_attr__( 'Add New Tag', 'bbpress' ),
3397 'new_item_name' => esc_attr__( 'New Tag Name', 'bbpress' ),
3398 'separate_items_with_commas' => esc_attr__( 'Separate topic tags with commas', 'bbpress' ),
3399 'add_or_remove_items' => esc_attr__( 'Add or remove tags', 'bbpress' ),
3400 'choose_from_most_used' => esc_attr__( 'Choose from the most used tags', 'bbpress' ),
3401 'not_found' => esc_attr__( 'No topic tags found.', 'bbpress' ),
3402 'no_terms' => esc_attr__( 'No topic tags', 'bbpress' ),
3403 'items_list_navigation' => esc_attr__( 'Topic tags list navigation', 'bbpress' ),
3404 'items_list' => esc_attr__( 'Topic tags list', 'bbpress' ),
3405 'most_used' => esc_attr__( 'Most used topic tags', 'bbpress' ),
3406 'back_to_items' => esc_attr__( '&larr; Back to Tags', 'bbpress' )
3407 ) );
3408 }
3409
3410 /**
3411 * Return an array of topic-tag taxonomy rewrite settings
3412 *
3413 * @since 2.5.0 bbPress (r5129)
3414 *
3415 * @return array
3416 */
3417 function bbp_get_topic_tag_tax_rewrite() {
3418
3419 // Filter & return
3420 return (array) apply_filters( 'bbp_get_topic_tag_tax_rewrite', array(
3421 'slug' => bbp_get_topic_tag_tax_slug(),
3422 'with_front' => false
3423 ) );
3424 }
3425
3426 /**
3427 * Output the id of the current tag
3428 *
3429 * @since 2.0.0 bbPress (r3109)
3430 *
3431 */
3432 function bbp_topic_tag_id( $tag = '' ) {
3433 echo bbp_get_topic_tag_id( $tag );
3434 }
3435 /**
3436 * Return the id of the current tag
3437 *
3438 * @since 2.0.0 bbPress (r3109)
3439 *
3440 * @return string Term Name
3441 */
3442 function bbp_get_topic_tag_id( $tag = '' ) {
3443
3444 // Get the term
3445 if ( ! empty( $tag ) ) {
3446 $term = get_term_by( 'slug', $tag, bbp_get_topic_tag_tax_id() );
3447 } else {
3448 $tag = get_query_var( 'term' );
3449 $term = get_queried_object();
3450 }
3451
3452 // Get the term ID
3453 $retval = ! empty( $term->term_id )
3454 ? $term->term_id
3455 : 0;
3456
3457 // Filter & return
3458 return (int) apply_filters( 'bbp_get_topic_tag_id', (int) $retval, $tag, $term );
3459 }
3460
3461 /**
3462 * Output the name of the current tag
3463 *
3464 * @since 2.0.0 bbPress (r3109)
3465 */
3466 function bbp_topic_tag_name( $tag = '' ) {
3467 echo bbp_get_topic_tag_name( $tag );
3468 }
3469 /**
3470 * Return the name of the current tag
3471 *
3472 * @since 2.0.0 bbPress (r3109)
3473 *
3474 * @return string Term Name
3475 */
3476 function bbp_get_topic_tag_name( $tag = '' ) {
3477
3478 // Get the term
3479 if ( ! empty( $tag ) ) {
3480 $term = get_term_by( 'slug', $tag, bbp_get_topic_tag_tax_id() );
3481 } else {
3482 $tag = get_query_var( 'term' );
3483 $term = get_queried_object();
3484 }
3485
3486 // Get the term name
3487 $retval = ! empty( $term->name )
3488 ? $term->name
3489 : '';
3490
3491 // Filter & return
3492 return apply_filters( 'bbp_get_topic_tag_name', $retval, $tag, $term );
3493 }
3494
3495 /**
3496 * Output the slug of the current tag
3497 *
3498 * @since 2.0.0 bbPress (r3109)
3499 */
3500 function bbp_topic_tag_slug( $tag = '' ) {
3501 echo bbp_get_topic_tag_slug( $tag );
3502 }
3503 /**
3504 * Return the slug of the current tag
3505 *
3506 * @since 2.0.0 bbPress (r3109)
3507 *
3508 * @return string Term Name
3509 */
3510 function bbp_get_topic_tag_slug( $tag = '' ) {
3511
3512 // Get the term
3513 if ( ! empty( $tag ) ) {
3514 $term = get_term_by( 'slug', $tag, bbp_get_topic_tag_tax_id() );
3515 } else {
3516 $tag = get_query_var( 'term' );
3517 $term = get_queried_object();
3518 }
3519
3520 // Get the term slug
3521 $retval = ! empty( $term->slug )
3522 ? $term->slug
3523 : '';
3524
3525 // Filter & return
3526 return apply_filters( 'bbp_get_topic_tag_slug', $retval, $tag, $term );
3527 }
3528
3529 /**
3530 * Output the link of the current tag
3531 *
3532 * @since 2.0.0 bbPress (r3348)
3533 */
3534 function bbp_topic_tag_link( $tag = '' ) {
3535 echo esc_url( bbp_get_topic_tag_link( $tag ) );
3536 }
3537 /**
3538 * Return the link of the current tag
3539 *
3540 * @since 2.0.0 bbPress (r3348)
3541 *
3542 * @return string Term Name
3543 */
3544 function bbp_get_topic_tag_link( $tag = '' ) {
3545
3546 // Get the term
3547 if ( ! empty( $tag ) ) {
3548 $term = get_term_by( 'slug', $tag, bbp_get_topic_tag_tax_id() );
3549 } else {
3550 $tag = get_query_var( 'term' );
3551 $term = get_queried_object();
3552 }
3553
3554 // Get the term link
3555 $retval = ! empty( $term->term_id )
3556 ? get_term_link( $term, bbp_get_topic_tag_tax_id() )
3557 : '';
3558
3559 // Filter & return
3560 return apply_filters( 'bbp_get_topic_tag_link', $retval, $tag, $term );
3561 }
3562
3563 /**
3564 * Output the link of the current tag
3565 *
3566 * @since 2.0.0 bbPress (r3348)
3567 */
3568 function bbp_topic_tag_edit_link( $tag = '' ) {
3569 echo esc_url( bbp_get_topic_tag_edit_link( $tag ) );
3570 }
3571 /**
3572 * Return the link of the current tag
3573 *
3574 * @since 2.0.0 bbPress (r3348)
3575 *
3576 * @return string Term Name
3577 */
3578 function bbp_get_topic_tag_edit_link( $tag = '' ) {
3579
3580 // Get the term
3581 if ( ! empty( $tag ) ) {
3582 $term = get_term_by( 'slug', $tag, bbp_get_topic_tag_tax_id() );
3583 } else {
3584 $tag = get_query_var( 'term' );
3585 $term = get_queried_object();
3586 }
3587
3588 // Get the term's edit link
3589 if ( ! empty( $term->term_id ) ) {
3590
3591 // Pretty or ugly URL
3592 $retval = bbp_use_pretty_urls()
3593 ? user_trailingslashit( trailingslashit( bbp_get_topic_tag_link() ) . bbp_get_edit_slug() )
3594 : add_query_arg( array( bbp_get_edit_rewrite_id() => '1' ), bbp_get_topic_tag_link() );
3595
3596 // No link
3597 } else {
3598 $retval = '';
3599 }
3600
3601 // Filter & return
3602 return apply_filters( 'bbp_get_topic_tag_edit_link', $retval, $tag, $term );
3603 }
3604
3605 /**
3606 * Output the description of the current tag
3607 *
3608 * @since 2.0.0 bbPress (r3109)
3609 */
3610 function bbp_topic_tag_description( $args = array() ) {
3611 echo bbp_get_topic_tag_description( $args );
3612 }
3613 /**
3614 * Return the description of the current tag
3615 *
3616 * @since 2.0.0 bbPress (r3109)
3617 *
3618 * @param array $args before|after|tag
3619 *
3620 * @return string Term Name
3621 */
3622 function bbp_get_topic_tag_description( $args = array() ) {
3623
3624 // Parse arguments against default values
3625 $r = bbp_parse_args( $args, array(
3626 'before' => '<div class="bbp-topic-tag-description"><p>',
3627 'after' => '</p></div>',
3628 'tag' => ''
3629 ), 'get_topic_tag_description' );
3630
3631 // Get the term
3632 if ( ! empty( $r['tag'] ) ) {
3633 $term = get_term_by( 'slug', $r['tag'], bbp_get_topic_tag_tax_id() );
3634 } else {
3635 $tag = $r['tag'] = get_query_var( 'term' );
3636 $term = get_queried_object();
3637 }
3638
3639 // Add before & after if description exists
3640 $retval = ! empty( $term->description )
3641 ? $r['before'] . $term->description . $r['after']
3642 : '';
3643
3644 // Filter & return
3645 return apply_filters( 'bbp_get_topic_tag_description', $retval, $r, $args, $tag, $term );
3646 }
3647
3648 /** Forms *********************************************************************/
3649
3650 /**
3651 * Output the value of topic title field
3652 *
3653 * @since 2.0.0 bbPress (r2976)
3654 */
3655 function bbp_form_topic_title() {
3656 echo bbp_get_form_topic_title();
3657 }
3658 /**
3659 * Return the value of topic title field
3660 *
3661 * @since 2.0.0 bbPress (r2976)
3662 *
3663 * @return string Value of topic title field
3664 */
3665 function bbp_get_form_topic_title() {
3666
3667 // Get _POST data
3668 if ( bbp_is_topic_form_post_request() && isset( $_POST['bbp_topic_title'] ) ) {
3669 $topic_title = wp_unslash( $_POST['bbp_topic_title'] );
3670
3671 // Get edit data
3672 } elseif ( bbp_is_topic_edit() ) {
3673 $topic_title = bbp_get_global_post_field( 'post_title', 'raw' );
3674
3675 // No data
3676 } else {
3677 $topic_title = '';
3678 }
3679
3680 // Filter & return
3681 return apply_filters( 'bbp_get_form_topic_title', $topic_title );
3682 }
3683
3684 /**
3685 * Output the value of topic content field
3686 *
3687 * @since 2.0.0 bbPress (r2976)
3688 */
3689 function bbp_form_topic_content() {
3690 echo bbp_get_form_topic_content();
3691 }
3692 /**
3693 * Return the value of topic content field
3694 *
3695 * @since 2.0.0 bbPress (r2976)
3696 *
3697 * @return string Value of topic content field
3698 */
3699 function bbp_get_form_topic_content() {
3700
3701 // Get _POST data
3702 if ( bbp_is_topic_form_post_request() && isset( $_POST['bbp_topic_content'] ) ) {
3703 $topic_content = wp_unslash( $_POST['bbp_topic_content'] );
3704
3705 // Get edit data
3706 } elseif ( bbp_is_topic_edit() ) {
3707 $topic_content = bbp_get_global_post_field( 'post_content', 'raw' );
3708
3709 // No data
3710 } else {
3711 $topic_content = '';
3712 }
3713
3714 // Filter & return
3715 return apply_filters( 'bbp_get_form_topic_content', $topic_content );
3716 }
3717
3718 /**
3719 * Allow topic rows to have administrative actions
3720 *
3721 * @since 2.1.0 bbPress (r3653)
3722 *
3723 * @todo Links and filter
3724 */
3725 function bbp_topic_row_actions() {
3726 do_action( 'bbp_topic_row_actions' );
3727 }
3728
3729 /**
3730 * Output value of topic tags field
3731 *
3732 * @since 2.0.0 bbPress (r2976)
3733 */
3734 function bbp_form_topic_tags() {
3735 echo bbp_get_form_topic_tags();
3736 }
3737 /**
3738 * Return value of topic tags field
3739 *
3740 * @since 2.0.0 bbPress (r2976)
3741 *
3742 * @return string Value of topic tags field
3743 */
3744 function bbp_get_form_topic_tags() {
3745
3746 // Default return value
3747 $topic_tags = '';
3748
3749 // Get _POST data
3750 if ( ( bbp_is_topic_form_post_request() || bbp_is_reply_form_post_request() ) && isset( $_POST['bbp_topic_tags'] ) ) {
3751 $topic_tags = wp_unslash( $_POST['bbp_topic_tags'] );
3752
3753 // Get edit data
3754 } elseif ( bbp_is_single_topic() || bbp_is_single_reply() || bbp_is_topic_edit() || bbp_is_reply_edit() ) {
3755
3756 // Determine the topic id based on the post type
3757 switch ( get_post_type() ) {
3758
3759 // Post is a topic
3760 case bbp_get_topic_post_type() :
3761 $topic_id = bbp_get_topic_id( get_the_ID() );
3762 break;
3763
3764 // Post is a reply
3765 case bbp_get_reply_post_type() :
3766 $topic_id = bbp_get_reply_topic_id( get_the_ID() );
3767 break;
3768 }
3769
3770 // Topic exists
3771 if ( ! empty( $topic_id ) ) {
3772
3773 // Topic is spammed so display pre-spam terms
3774 if ( bbp_is_topic_spam( $topic_id ) ) {
3775
3776 // Get pre-spam terms
3777 $spam_terms = get_post_meta( $topic_id, '_bbp_spam_topic_tags', true );
3778 $topic_tags = ( ! empty( $spam_terms ) ) ? implode( ', ', $spam_terms ) : '';
3779
3780 // Topic is not spam so get real terms
3781 } else {
3782 $topic_tags = bbp_get_topic_tag_names( $topic_id );
3783 }
3784 }
3785 }
3786
3787 // Filter & return
3788 return apply_filters( 'bbp_get_form_topic_tags', $topic_tags );
3789 }
3790
3791 /**
3792 * Output value of topic forum
3793 *
3794 * @since 2.0.0 bbPress (r2976)
3795 */
3796 function bbp_form_topic_forum() {
3797 echo bbp_get_form_topic_forum();
3798 }
3799 /**
3800 * Return value of topic forum
3801 *
3802 * @since 2.0.0 bbPress (r2976)
3803 *
3804 * @return string Value of topic content field
3805 */
3806 function bbp_get_form_topic_forum() {
3807
3808 // Get _POST data
3809 if ( bbp_is_topic_form_post_request() && isset( $_POST['bbp_forum_id'] ) ) {
3810 $topic_forum = (int) $_POST['bbp_forum_id'];
3811
3812 // Get edit data
3813 } elseif ( bbp_is_topic_edit() ) {
3814 $topic_forum = bbp_get_topic_forum_id();
3815
3816 // No data
3817 } else {
3818 $topic_forum = 0;
3819 }
3820
3821 // Filter & return
3822 return apply_filters( 'bbp_get_form_topic_forum', $topic_forum );
3823 }
3824
3825 /**
3826 * Output checked value of topic subscription
3827 *
3828 * @since 2.0.0 bbPress (r2976)
3829 */
3830 function bbp_form_topic_subscribed() {
3831 echo bbp_get_form_topic_subscribed();
3832 }
3833 /**
3834 * Return checked value of topic subscription
3835 *
3836 * @since 2.0.0 bbPress (r2976)
3837 *
3838 * @return string Checked value of topic subscription
3839 */
3840 function bbp_get_form_topic_subscribed() {
3841
3842 // Default value
3843 $topic_subscribed = false;
3844
3845 // Get _POST data
3846 if ( bbp_is_topic_form_post_request() && isset( $_POST['bbp_topic_subscription'] ) ) {
3847 $topic_subscribed = (bool) $_POST['bbp_topic_subscription'];
3848
3849 // Get edit data
3850 } elseif ( bbp_is_topic_edit() || bbp_is_reply_edit() ) {
3851 $post_author = (int) bbp_get_global_post_field( 'post_author', 'raw' );
3852 $topic_subscribed = bbp_is_user_subscribed( $post_author, bbp_get_topic_id() );
3853
3854 // Get current status
3855 } elseif ( bbp_is_single_topic() ) {
3856 $topic_subscribed = bbp_is_user_subscribed( bbp_get_current_user_id(), bbp_get_topic_id() );
3857 }
3858
3859 // Get checked output
3860 $checked = checked( $topic_subscribed, true, false );
3861
3862 // Filter & return
3863 return apply_filters( 'bbp_get_form_topic_subscribed', $checked, $topic_subscribed );
3864 }
3865
3866 /**
3867 * Output checked value of topic log edit field
3868 *
3869 * @since 2.0.0 bbPress (r2976)
3870 */
3871 function bbp_form_topic_log_edit() {
3872 echo bbp_get_form_topic_log_edit();
3873 }
3874 /**
3875 * Return checked value of topic log edit field
3876 *
3877 * @since 2.0.0 bbPress (r2976)
3878 *
3879 * @return string Topic log edit checked value
3880 */
3881 function bbp_get_form_topic_log_edit() {
3882
3883 // Get _POST data
3884 if ( bbp_is_topic_form_post_request() && isset( $_POST['bbp_log_topic_edit'] ) ) {
3885 $topic_revision = (bool) $_POST['bbp_log_topic_edit'];
3886
3887 // No data
3888 } else {
3889 $topic_revision = true;
3890 }
3891
3892 // Get checked output
3893 $checked = checked( $topic_revision, true, false );
3894
3895 // Filter & return
3896 return apply_filters( 'bbp_get_form_topic_log_edit', $checked, $topic_revision );
3897 }
3898
3899 /**
3900 * Output the value of the topic edit reason
3901 *
3902 * @since 2.0.0 bbPress (r2976)
3903 */
3904 function bbp_form_topic_edit_reason() {
3905 echo bbp_get_form_topic_edit_reason();
3906 }
3907 /**
3908 * Return the value of the topic edit reason
3909 *
3910 * @since 2.0.0 bbPress (r2976)
3911 *
3912 * @return string Topic edit reason value
3913 */
3914 function bbp_get_form_topic_edit_reason() {
3915
3916 // Get _POST data
3917 if ( bbp_is_topic_form_post_request() && isset( $_POST['bbp_topic_edit_reason'] ) ) {
3918 $topic_edit_reason = wp_unslash( $_POST['bbp_topic_edit_reason'] );
3919
3920 // No data
3921 } else {
3922 $topic_edit_reason = '';
3923 }
3924
3925 // Filter & return
3926 return apply_filters( 'bbp_get_form_topic_edit_reason', $topic_edit_reason );
3927 }
3928
3929 /**
3930 * Verify if a POST request came from a failed topic attempt.
3931 *
3932 * Used to avoid cross-site request forgeries when checking posted topic form
3933 * content.
3934 *
3935 * @see bbp_topic_form_fields()
3936 *
3937 * @since 2.6.0 bbPress (r5558)
3938 *
3939 * @return boolean True if is a post request with valid nonce
3940 */
3941 function bbp_is_topic_form_post_request() {
3942
3943 // Bail if not a post request
3944 if ( ! bbp_is_post_request() ) {
3945 return false;
3946 }
3947
3948 // Creating a new topic
3949 if ( bbp_verify_nonce_request( 'bbp-new-topic' ) ) {
3950 return true;
3951 }
3952
3953 // Editing an existing topic
3954 if ( bbp_verify_nonce_request( 'bbp-edit-topic_' . bbp_get_topic_id() ) ) {
3955 return true;
3956 }
3957
3958 return false;
3959 }
3960
3961 /** Warning *******************************************************************/
3962
3963 /**
3964 * Should the topic-lock alert appear?
3965 *
3966 * @since 2.6.0 bbPress (r6342)
3967 *
3968 * @return bool
3969 */
3970 function bbp_show_topic_lock_alert() {
3971
3972 // Default to not showing the alert
3973 $retval = false;
3974
3975 // Get the current topic ID
3976 $topic_id = bbp_get_topic_id();
3977
3978 // Only show on single topic pages
3979 if ( bbp_is_topic_edit() || bbp_is_single_topic() ) {
3980
3981 // Only show to moderators
3982 if ( current_user_can( 'moderate', $topic_id ) ) {
3983
3984 // Locked?
3985 $user_id = bbp_check_post_lock( $topic_id );
3986
3987 // Only show if not locked by the current user
3988 if ( ! empty( $user_id ) && ( bbp_get_current_user_id() !== $user_id ) ) {
3989 $retval = true;
3990 }
3991 }
3992 }
3993
3994 // Filter & return
3995 return (bool) apply_filters( 'bbp_show_topic_lock_alert', $retval, $topic_id );
3996 }
3997
3998 /**
3999 * Output the topic lock description
4000 *
4001 * @since 2.6.0 bbPress (r6343)
4002 *
4003 * @param int $topic_id Optional. Topic id
4004 */
4005 function bbp_topic_lock_description( $topic_id = 0 ) {
4006 echo bbp_get_topic_lock_description( $topic_id );
4007 }
4008 /**
4009 * Return the topic lock description
4010 *
4011 * @since 2.6.0 bbPress (r6343)
4012 *
4013 * @param int $topic_id Optional. Topic id
4014 */
4015 function bbp_get_topic_lock_description( $topic_id = 0 ) {
4016
4017 // Check if topic is edit locked
4018 $topic_id = bbp_get_topic_id( $topic_id );
4019 $user_id = bbp_check_post_lock( $topic_id );
4020 $person = empty( $user_id )
4021 ? esc_html__( 'Nobody', 'bbpress' )
4022 : bbp_get_user_profile_link( $user_id );
4023
4024 // Get the text
4025 $text = sprintf( esc_html__( '%1$s is currently editing this topic.', 'bbpress' ), $person );
4026
4027 // Filter & return
4028 return apply_filters( 'bbp_get_topic_lock_description', $text, $user_id, $topic_id );
4029 }
4030