PluginProbe
bbPress / 2.6.19
bbPress v2.6.19
2.6.19 2.6.18 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 All 74 releases
bbpress / includes / topics / template.php

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

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