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

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

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