[ Index ]

PHP Cross Reference of BBPress

title

Body

[close]

/src/includes/topics/ -> template.php (source)

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


Generated: Wed May 22 01:01:34 2019 Cross-referenced by PHPXref 0.7.1