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

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

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