PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / 2.0.0
Forumax – AI Powered Advanced Community Forum Plugin v2.0.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 / vendor / bbpress / includes / topics / template.php

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

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