[ Index ]

PHP Cross Reference of BBPress

title

Body

[close]

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

   1  <?php
   2  
   3  /**
   4   * bbPress Reply 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   * Return the unique id of the custom post type for replies
  17   *
  18   * @since 2.0.0 bbPress (r2857)
  19   *
  20   */
  21  function bbp_reply_post_type() {
  22      echo bbp_get_reply_post_type();
  23  }
  24      /**
  25       * Return the unique id of the custom post type for replies
  26       *
  27       * @since 2.0.0 bbPress (r2857)
  28       *
  29       *                        post type id
  30       * @return string The unique reply post type id
  31       */
  32  	function bbp_get_reply_post_type() {
  33  
  34          // Filter & return
  35          return apply_filters( 'bbp_get_reply_post_type', bbpress()->reply_post_type );
  36      }
  37  
  38  /**
  39   * Return array of labels used by the reply post type
  40   *
  41   * @since 2.5.0 bbPress (r5129)
  42   *
  43   * @return array
  44   */
  45  function bbp_get_reply_post_type_labels() {
  46  
  47      // Filter & return
  48      return (array) apply_filters( 'bbp_get_reply_post_type_labels', array(
  49          'name'                     => esc_attr__( 'Replies',                    'bbpress' ),
  50          'menu_name'                => esc_attr__( 'Replies',                    'bbpress' ),
  51          'singular_name'            => esc_attr_x( 'Reply', 'noun',              'bbpress' ),
  52          'all_items'                => esc_attr__( 'All Replies',                'bbpress' ),
  53          'add_new'                  => esc_attr__( 'Add New',                    'bbpress' ),
  54          'add_new_item'             => esc_attr__( 'Create New Reply',           'bbpress' ),
  55          'edit'                     => esc_attr__( 'Edit',                       'bbpress' ),
  56          'edit_item'                => esc_attr__( 'Edit Reply',                 'bbpress' ),
  57          'new_item'                 => esc_attr__( 'New Reply',                  'bbpress' ),
  58          'view'                     => esc_attr__( 'View Reply',                 'bbpress' ),
  59          'view_item'                => esc_attr__( 'View Reply',                 'bbpress' ),
  60          'view_items'               => esc_attr__( 'View Replies',               'bbpress' ),
  61          'search_items'             => esc_attr__( 'Search Replies',             'bbpress' ),
  62          'not_found'                => esc_attr__( 'No replies found',           'bbpress' ),
  63          'not_found_in_trash'       => esc_attr__( 'No replies found in Trash',  'bbpress' ),
  64          'filter_items_list'        => esc_attr__( 'Filter replies list',        'bbpress' ),
  65          'items_list'               => esc_attr__( 'Replies list',               'bbpress' ),
  66          'items_list_navigation'    => esc_attr__( 'Replies list navigation',    'bbpress' ),
  67          'parent_item_colon'        => esc_attr__( 'Parent Topic:',              'bbpress' ),
  68          'archives'                 => esc_attr__( 'Forum Replies',              'bbpress' ),
  69          'attributes'               => esc_attr__( 'Reply Attributes',           'bbpress' ),
  70          'insert_into_item'         => esc_attr__( 'Insert into reply',          'bbpress' ),
  71          'uploaded_to_this_item'    => esc_attr__( 'Uploaded to this reply',     'bbpress' ),
  72          'featured_image'           => esc_attr__( 'Reply Image',                'bbpress' ),
  73          'set_featured_image'       => esc_attr__( 'Set reply image',            'bbpress' ),
  74          'remove_featured_image'    => esc_attr__( 'Remove reply image',         'bbpress' ),
  75          'use_featured_image'       => esc_attr__( 'Use as reply image',         'bbpress' ),
  76          'item_published'           => esc_attr__( 'Reply published.',           'bbpress' ),
  77          'item_published_privately' => esc_attr__( 'Reply published privately.', 'bbpress' ),
  78          'item_reverted_to_draft'   => esc_attr__( 'Reply reverted to draft.',   'bbpress' ),
  79          'item_scheduled'           => esc_attr__( 'Reply scheduled.',           'bbpress' ),
  80          'item_updated'             => esc_attr__( 'Reply updated.',             'bbpress' )
  81      ) );
  82  }
  83  
  84  /**
  85   * Return array of reply post type rewrite settings
  86   *
  87   * @since 2.5.0 bbPress (r5129)
  88   *
  89   * @return array
  90   */
  91  function bbp_get_reply_post_type_rewrite() {
  92  
  93      // Filter & return
  94      return (array) apply_filters( 'bbp_get_reply_post_type_rewrite', array(
  95          'slug'       => bbp_get_reply_slug(),
  96          'with_front' => false
  97      ) );
  98  }
  99  
 100  /**
 101   * Return array of features the reply post type supports
 102   *
 103   * @since 2.5.0 bbPress (r5129)
 104   *
 105   * @return array
 106   */
 107  function bbp_get_reply_post_type_supports() {
 108  
 109      // Filter & return
 110      return (array) apply_filters( 'bbp_get_reply_post_type_supports', array(
 111          'title',
 112          'editor',
 113          'revisions'
 114      ) );
 115  }
 116  
 117  /** Reply Loop Functions ******************************************************/
 118  
 119  /**
 120   * The main reply loop. WordPress makes this easy for us
 121   *
 122   * @since 2.0.0 bbPress (r2553)
 123   *
 124   * @param array $args All the arguments supported by {@link WP_Query}
 125   * @return object Multidimensional array of reply information
 126   */
 127  function bbp_has_replies( $args = array() ) {
 128  
 129      /** Defaults **************************************************************/
 130  
 131      // Other defaults
 132      $default_reply_search   = bbp_sanitize_search_request( 'rs' );
 133      $default_post_parent    = ( bbp_is_single_topic() ) ? bbp_get_topic_id() : 'any';
 134      $default_post_type      = ( bbp_is_single_topic() && bbp_show_lead_topic() ) ? bbp_get_reply_post_type() : array( bbp_get_topic_post_type(), bbp_get_reply_post_type() );
 135      $default_thread_replies = (bool) ( bbp_is_single_topic() && bbp_thread_replies() );
 136  
 137      // Default query args
 138      $default = array(
 139          'post_type'              => $default_post_type,         // Only replies
 140          'post_parent'            => $default_post_parent,       // Of this topic
 141          'posts_per_page'         => bbp_get_replies_per_page(), // This many
 142          'paged'                  => bbp_get_paged(),            // On this page
 143          'orderby'                => 'date',                     // Sorted by date
 144          'order'                  => 'ASC',                      // Oldest to newest
 145          'hierarchical'           => $default_thread_replies,    // Hierarchical replies
 146          'ignore_sticky_posts'    => true,                       // Stickies not supported
 147          'update_post_term_cache' => false,                      // No terms to cache
 148  
 149          // Conditionally prime the cache for all related posts
 150          'update_post_family_cache' => true
 151      );
 152  
 153      // Only add 's' arg if searching for replies
 154      // See https://bbpress.trac.wordpress.org/ticket/2607
 155      if ( ! empty( $default_reply_search ) ) {
 156          $default['s'] = $default_reply_search;
 157      }
 158  
 159      // What are the default allowed statuses (based on user caps)
 160      if ( bbp_get_view_all( 'edit_others_replies' ) ) {
 161  
 162          // Default view=all statuses
 163          $post_statuses = array_keys( bbp_get_topic_statuses() );
 164  
 165          // Add support for private status
 166          if ( current_user_can( 'read_private_replies' ) ) {
 167              $post_statuses[] = bbp_get_private_status_id();
 168          }
 169  
 170          // Join post statuses together
 171          $default['post_status'] = $post_statuses;
 172  
 173      // Lean on the 'perm' query var value of 'readable' to provide statuses
 174      } else {
 175          $default['perm'] = 'readable';
 176      }
 177  
 178      /** Setup *****************************************************************/
 179  
 180      // Parse arguments against default values
 181      $r = bbp_parse_args( $args, $default, 'has_replies' );
 182  
 183      // Set posts_per_page value if replies are threaded
 184      $replies_per_page = (int) $r['posts_per_page'];
 185      if ( true === $r['hierarchical'] ) {
 186          $r['posts_per_page'] = -1;
 187      }
 188  
 189      // Get bbPress
 190      $bbp = bbpress();
 191  
 192      // Call the query
 193      $bbp->reply_query = new WP_Query( $r );
 194  
 195      // Maybe prime the post author caches
 196      if ( ! empty( $r['update_post_family_cache'] ) ) {
 197          bbp_update_post_family_caches( $bbp->reply_query->posts );
 198      }
 199  
 200      // Add pagination values to query object
 201      $bbp->reply_query->posts_per_page = (int) $replies_per_page;
 202      $bbp->reply_query->paged          = (int) $r['paged'];
 203  
 204      // Never home, regardless of what parse_query says
 205      $bbp->reply_query->is_home        = false;
 206  
 207      // Reset is_single if single topic
 208      if ( bbp_is_single_topic() ) {
 209          $bbp->reply_query->is_single = true;
 210      }
 211  
 212      // Only add reply to if query returned results
 213      if ( ! empty( $bbp->reply_query->found_posts ) ) {
 214  
 215          // Get reply to for each reply
 216          foreach ( $bbp->reply_query->posts as &$post ) {
 217  
 218              // Check for reply post type
 219              if ( bbp_get_reply_post_type() === $post->post_type ) {
 220                  $reply_to = bbp_get_reply_to( $post->ID );
 221  
 222                  // Make sure it's a reply to a reply
 223                  if ( empty( $reply_to ) || ( bbp_get_reply_topic_id( $post->ID ) === $reply_to ) ) {
 224                      $reply_to = 0;
 225                  }
 226  
 227                  // Add reply_to to the post object so we can walk it later
 228                  $post->reply_to = $reply_to;
 229              }
 230          }
 231      }
 232  
 233      // Only add pagination if query returned results
 234      if ( ! empty( $bbp->reply_query->found_posts ) && ! empty( $bbp->reply_query->posts_per_page ) ) {
 235  
 236          // Figure out total pages
 237          if ( true === $r['hierarchical'] ) {
 238              $walker      = new BBP_Walker_Reply;
 239              $total_pages = ceil( $walker->get_number_of_root_elements( $bbp->reply_query->posts ) / $bbp->reply_query->posts_per_page );
 240          } else {
 241  
 242              // Total for pagination boundaries
 243              $total_pages = ( $bbp->reply_query->posts_per_page === $bbp->reply_query->found_posts )
 244                  ? 1
 245                  : ceil( $bbp->reply_query->found_posts / $bbp->reply_query->posts_per_page );
 246  
 247              // Pagination settings with filter
 248              $bbp_replies_pagination = apply_filters( 'bbp_replies_pagination', array(
 249                  'base'    => bbp_get_replies_pagination_base( bbp_get_topic_id() ),
 250                  'total'   => $total_pages,
 251                  'current' => $bbp->reply_query->paged
 252              ) );
 253  
 254              // Add pagination to query object
 255              $bbp->reply_query->pagination_links = bbp_paginate_links( $bbp_replies_pagination );
 256          }
 257      }
 258  
 259      // Filter & return
 260      return apply_filters( 'bbp_has_replies', $bbp->reply_query->have_posts(), $bbp->reply_query );
 261  }
 262  
 263  /**
 264   * Whether there are more replies available in the loop
 265   *
 266   * @since 2.0.0 bbPress (r2553)
 267   *
 268   * @return object Replies information
 269   */
 270  function bbp_replies() {
 271  
 272      // Put into variable to check against next
 273      $have_posts = bbpress()->reply_query->have_posts();
 274  
 275      // Reset the post data when finished
 276      if ( empty( $have_posts ) ) {
 277          wp_reset_postdata();
 278      }
 279  
 280      return $have_posts;
 281  }
 282  
 283  /**
 284   * Loads up the current reply in the loop
 285   *
 286   * @since 2.0.0 bbPress (r2553)
 287   *
 288   * @return object Reply information
 289   */
 290  function bbp_the_reply() {
 291      return bbpress()->reply_query->the_post();
 292  }
 293  
 294  /**
 295   * Output reply id
 296   *
 297   * @since 2.0.0 bbPress (r2553)
 298   *
 299   * @param $reply_id Optional. Used to check emptiness
 300   */
 301  function bbp_reply_id( $reply_id = 0 ) {
 302      echo bbp_get_reply_id( $reply_id );
 303  }
 304      /**
 305       * Return the id of the reply in a replies loop
 306       *
 307       * @since 2.0.0 bbPress (r2553)
 308       *
 309       * @param $reply_id Optional. Used to check emptiness
 310       * @return int The reply id
 311       */
 312  	function bbp_get_reply_id( $reply_id = 0 ) {
 313          $bbp      = bbpress();
 314          $wp_query = bbp_get_wp_query();
 315  
 316          // Easy empty checking
 317          if ( ! empty( $reply_id ) && is_numeric( $reply_id ) ) {
 318              $bbp_reply_id = $reply_id;
 319  
 320          // Currently inside a replies loop
 321          } elseif ( ! empty( $bbp->reply_query->in_the_loop ) && isset( $bbp->reply_query->post->ID ) ) {
 322              $bbp_reply_id = $bbp->reply_query->post->ID;
 323  
 324          // Currently inside a search loop
 325          } elseif ( ! empty( $bbp->search_query->in_the_loop ) && isset( $bbp->search_query->post->ID ) && bbp_is_reply( $bbp->search_query->post->ID ) ) {
 326              $bbp_reply_id = $bbp->search_query->post->ID;
 327  
 328          // Currently viewing a forum
 329          } elseif ( ( bbp_is_single_reply() || bbp_is_reply_edit() ) && ! empty( $bbp->current_reply_id ) ) {
 330              $bbp_reply_id = $bbp->current_reply_id;
 331  
 332          // Currently viewing a reply
 333          } elseif ( ( bbp_is_single_reply() || bbp_is_reply_edit() ) && isset( $wp_query->post->ID ) ) {
 334              $bbp_reply_id = $wp_query->post->ID;
 335  
 336          // Fallback
 337          } else {
 338              $bbp_reply_id = 0;
 339          }
 340  
 341          // Filter & return
 342          return (int) apply_filters( 'bbp_get_reply_id', $bbp_reply_id, $reply_id );
 343      }
 344  
 345  /**
 346   * Gets a reply
 347   *
 348   * @since 2.0.0 bbPress (r2787)
 349   *
 350   * @param int|object $reply reply id or reply object
 351   * @param string $output Optional. OBJECT, ARRAY_A, or ARRAY_N. Default = OBJECT
 352   * @param string $filter Optional Sanitation filter. See {@link sanitize_post()}
 353   * @return mixed Null if error or reply (in specified form) if success
 354   */
 355  function bbp_get_reply( $reply, $output = OBJECT, $filter = 'raw' ) {
 356  
 357      // Maybe get ID from empty or int
 358      if ( empty( $reply ) || is_numeric( $reply ) ) {
 359          $reply = bbp_get_reply_id( $reply );
 360      }
 361  
 362      // Bail if no post object
 363      $reply = get_post( $reply, OBJECT, $filter );
 364      if ( empty( $reply ) ) {
 365          return $reply;
 366      }
 367  
 368      // Bail if not correct post type
 369      if ( $reply->post_type !== bbp_get_reply_post_type() ) {
 370          return null;
 371      }
 372  
 373      // Default return value is OBJECT
 374      $retval = $reply;
 375  
 376      // Array A
 377      if ( $output === ARRAY_A ) {
 378          $retval = get_object_vars( $reply );
 379  
 380      // Array N
 381      } elseif ( $output === ARRAY_N ) {
 382          $retval = array_values( get_object_vars( $reply ) );
 383      }
 384  
 385      // Filter & return
 386      return apply_filters( 'bbp_get_reply', $retval, $reply, $output, $filter );
 387  }
 388  
 389  /**
 390   * Output the link to the reply in the reply loop
 391   *
 392   * @since 2.0.0 bbPress (r2553)
 393   *
 394   * @param int $reply_id Optional. Reply id
 395   */
 396  function bbp_reply_permalink( $reply_id = 0 ) {
 397      echo esc_url( bbp_get_reply_permalink( $reply_id ) );
 398  }
 399      /**
 400       * Return the link to the reply
 401       *
 402       * @since 2.0.0 bbPress (r2553)
 403       *
 404       * @param int $reply_id Optional. Reply id
 405       *                        and reply id
 406       * @return string Permanent link to reply
 407       */
 408  	function bbp_get_reply_permalink( $reply_id = 0 ) {
 409          $reply_id = bbp_get_reply_id( $reply_id );
 410  
 411          // Filter & return
 412          return apply_filters( 'bbp_get_reply_permalink', get_permalink( $reply_id ), $reply_id );
 413      }
 414  
 415  /**
 416   * Output the paginated url to the reply in the reply loop
 417   *
 418   * @since 2.0.0 bbPress (r2679)
 419   *
 420   * @param int $reply_id Optional. Reply id
 421   */
 422  function bbp_reply_url( $reply_id = 0 ) {
 423      echo esc_url( bbp_get_reply_url( $reply_id ) );
 424  }
 425      /**
 426       * Return the paginated url to the reply in the reply loop
 427       *
 428       * @since 2.0.0 bbPress (r2679)
 429       *
 430       * @param int $reply_id Optional. Reply id
 431       * @param string $redirect_to Optional. Pass a redirect value for use with
 432       *                              shortcodes and other fun things.
 433       * @return string Link to reply relative to paginated topic
 434       */
 435  	function bbp_get_reply_url( $reply_id = 0, $redirect_to = '' ) {
 436  
 437          // Set needed variables
 438          $reply_id   = bbp_get_reply_id      ( $reply_id );
 439          $topic_id   = bbp_get_reply_topic_id( $reply_id );
 440  
 441          // Hierarchical reply page
 442          if ( bbp_thread_replies() ) {
 443              $reply_page = 1;
 444  
 445          // Standard reply page
 446          } else {
 447              $reply_page = ceil( (int) bbp_get_reply_position( $reply_id, $topic_id ) / (int) bbp_get_replies_per_page() );
 448          }
 449  
 450          $reply_hash = '#post-' . $reply_id;
 451          $topic_link = bbp_get_topic_permalink( $topic_id, $redirect_to );
 452          $topic_url  = remove_query_arg( 'view', $topic_link );
 453  
 454          // Don't include pagination if on first page
 455          if ( 1 >= $reply_page ) {
 456              $url = user_trailingslashit( $topic_url ) . $reply_hash;
 457  
 458          // Include pagination
 459          } else {
 460  
 461              // Pretty permalinks
 462              if ( bbp_use_pretty_urls() ) {
 463                  $url = trailingslashit( $topic_url ) . trailingslashit( bbp_get_paged_slug() ) . $reply_page;
 464                  $url = user_trailingslashit( $url ) . $reply_hash;
 465  
 466              // Yucky links
 467              } else {
 468                  $url = add_query_arg( 'paged', $reply_page, $topic_url ) . $reply_hash;
 469              }
 470          }
 471  
 472          // Add topic view query arg back to end if it is set
 473          if ( bbp_get_view_all() ) {
 474              $url = bbp_add_view_all( $url );
 475          }
 476  
 477          // Filter & return
 478          return apply_filters( 'bbp_get_reply_url', $url, $reply_id, $redirect_to );
 479      }
 480  
 481  /**
 482   * Output the title of the reply
 483   *
 484   * @since 2.0.0 bbPress (r2553)
 485   *
 486   * @param int $reply_id Optional. Reply id
 487   */
 488  function bbp_reply_title( $reply_id = 0 ) {
 489      echo bbp_get_reply_title( $reply_id );
 490  }
 491  
 492      /**
 493       * Return the title of the reply
 494       *
 495       * @since 2.0.0 bbPress (r2553)
 496       *
 497       * @param int $reply_id Optional. Reply id
 498       * @return string Title of reply
 499       */
 500  	function bbp_get_reply_title( $reply_id = 0 ) {
 501          $reply_id = bbp_get_reply_id( $reply_id );
 502          $title    = get_the_title( $reply_id );
 503  
 504          // Filter & return
 505          return apply_filters( 'bbp_get_reply_title', $title, $reply_id );
 506      }
 507  
 508      /**
 509       * Get empty reply title fallback.
 510       *
 511       * @since 2.5.0 bbPress (r5177)
 512       *
 513       * @param string $post_title Required. Reply Title
 514       * @param int $post_id Required. Reply ID
 515       * @return string Title of reply
 516       */
 517  	function bbp_get_reply_title_fallback( $post_title = '', $post_id = 0 ) {
 518  
 519          // Bail if title not empty, or post is not a reply
 520          if ( ! empty( $post_title ) || ! bbp_is_reply( $post_id ) ) {
 521              return $post_title;
 522          }
 523  
 524          // Get reply topic title.
 525          $topic_title = bbp_get_reply_topic_title( $post_id );
 526  
 527          // Get empty reply title fallback.
 528          $reply_title = sprintf( esc_html__( 'Reply To: %s', 'bbpress' ), $topic_title );
 529  
 530          // Filter & return
 531          return apply_filters( 'bbp_get_reply_title_fallback', $reply_title, $post_id, $topic_title );
 532      }
 533  
 534  /**
 535   * Output the content of the reply
 536   *
 537   * @since 2.0.0 bbPress (r2553)
 538   *
 539   * @param int $reply_id Optional. reply id
 540   */
 541  function bbp_reply_content( $reply_id = 0 ) {
 542      echo bbp_get_reply_content( $reply_id );
 543  }
 544      /**
 545       * Return the content of the reply
 546       *
 547       * @since 2.0.0 bbPress (r2780)
 548       *
 549       * @param int $reply_id Optional. reply id
 550       * @return string Content of the reply
 551       */
 552  	function bbp_get_reply_content( $reply_id = 0 ) {
 553          $reply_id = bbp_get_reply_id( $reply_id );
 554  
 555          // Check if password is required
 556          if ( post_password_required( $reply_id ) ) {
 557              return get_the_password_form();
 558          }
 559  
 560          $content = get_post_field( 'post_content', $reply_id );
 561  
 562          // Filter & return
 563          return apply_filters( 'bbp_get_reply_content', $content, $reply_id );
 564      }
 565  
 566  /**
 567   * Output the excerpt of the reply
 568   *
 569   * @since 2.0.0 bbPress (r2751)
 570   *
 571   * @param int $reply_id Optional. Reply id
 572   * @param int $length Optional. Length of the excerpt. Defaults to 100 letters
 573   */
 574  function bbp_reply_excerpt( $reply_id = 0, $length = 100 ) {
 575      echo bbp_get_reply_excerpt( $reply_id, $length );
 576  }
 577      /**
 578       * Return the excerpt of the reply
 579       *
 580       * @since 2.0.0 bbPress (r2751)
 581       *
 582       * @param int $reply_id Optional. Reply id
 583       * @param int $length Optional. Length of the excerpt. Defaults to 100
 584       *                     letters
 585       * @return string Reply Excerpt
 586       */
 587  	function bbp_get_reply_excerpt( $reply_id = 0, $length = 100 ) {
 588          $reply_id = bbp_get_reply_id( $reply_id );
 589          $length   = (int) $length;
 590          $excerpt  = get_post_field( 'post_excerpt', $reply_id );
 591  
 592          if ( empty( $excerpt ) ) {
 593              $excerpt = bbp_get_reply_content( $reply_id );
 594          }
 595  
 596          $excerpt = trim ( strip_tags( $excerpt ) );
 597  
 598          // Multibyte support
 599          if ( function_exists( 'mb_strlen' ) ) {
 600              $excerpt_length = mb_strlen( $excerpt );
 601          } else {
 602              $excerpt_length = strlen( $excerpt );
 603          }
 604  
 605          if ( ! empty( $length ) && ( $excerpt_length > $length ) ) {
 606              $excerpt  = mb_substr( $excerpt, 0, $length - 1 );
 607              $excerpt .= '&hellip;';
 608          }
 609  
 610          // Filter & return
 611          return apply_filters( 'bbp_get_reply_excerpt', $excerpt, $reply_id, $length );
 612      }
 613  
 614  /**
 615   * Output the post date and time of a reply
 616   *
 617   * @since 2.2.0 bbPress (r4155)
 618   *
 619   * @param int $reply_id Optional. Reply id.
 620   * @param bool $humanize Optional. Humanize output using time_since
 621   * @param bool $gmt Optional. Use GMT
 622   */
 623  function bbp_reply_post_date( $reply_id = 0, $humanize = false, $gmt = false ) {
 624      echo bbp_get_reply_post_date( $reply_id, $humanize, $gmt );
 625  }
 626      /**
 627       * Return the post date and time of a reply
 628       *
 629       * @since 2.2.0 bbPress (r4155)
 630       *
 631       * @param int $reply_id Optional. Reply id.
 632       * @param bool $humanize Optional. Humanize output using time_since
 633       * @param bool $gmt Optional. Use GMT
 634       * @return string
 635       */
 636  	function bbp_get_reply_post_date( $reply_id = 0, $humanize = false, $gmt = false ) {
 637          $reply_id = bbp_get_reply_id( $reply_id );
 638  
 639          // 4 days, 4 hours ago
 640          if ( ! empty( $humanize ) ) {
 641              $gmt_s  = ! empty( $gmt ) ? 'G' : 'U';
 642              $date   = get_post_time( $gmt_s, $gmt, $reply_id );
 643              $time   = false; // For filter below
 644              $result = bbp_get_time_since( $date );
 645  
 646          // August 4, 2012 at 2:37 pm
 647          } else {
 648              $date   = get_post_time( get_option( 'date_format' ), $gmt, $reply_id, true );
 649              $time   = get_post_time( get_option( 'time_format' ), $gmt, $reply_id, true );
 650              $result = sprintf( _x( '%1$s at %2$s', 'date at time', 'bbpress' ), $date, $time );
 651          }
 652  
 653          // Filter & return
 654          return apply_filters( 'bbp_get_reply_post_date', $result, $reply_id, $humanize, $gmt, $date, $time );
 655      }
 656  
 657  /**
 658   * Append revisions to the reply content
 659   *
 660   * @since 2.0.0 bbPress (r2782)
 661   *
 662   * @param string $content Optional. Content to which we need to append the revisions to
 663   * @param int $reply_id Optional. Reply id
 664   * @return string Content with the revisions appended
 665   */
 666  function bbp_reply_content_append_revisions( $content = '', $reply_id = 0 ) {
 667  
 668      // Bail if in admin or feed
 669      if ( is_admin() || is_feed() ) {
 670          return $content;
 671      }
 672  
 673      // Validate the ID
 674      $reply_id = bbp_get_reply_id( $reply_id );
 675  
 676      // Filter & return
 677      return apply_filters( 'bbp_reply_append_revisions', $content . bbp_get_reply_revision_log( $reply_id ), $content, $reply_id );
 678  }
 679  
 680  /**
 681   * Output the revision log of the reply
 682   *
 683   * @since 2.0.0 bbPress (r2782)
 684   *
 685   * @param int $reply_id Optional. Reply id
 686   */
 687  function bbp_reply_revision_log( $reply_id = 0 ) {
 688      echo bbp_get_reply_revision_log( $reply_id );
 689  }
 690      /**
 691       * Return the formatted revision log of the reply
 692       *
 693       * @since 2.0.0 bbPress (r2782)
 694       *
 695       * @param int $reply_id Optional. Reply id
 696       * @return string Revision log of the reply
 697       */
 698  	function bbp_get_reply_revision_log( $reply_id = 0 ) {
 699  
 700          // Create necessary variables
 701          $reply_id = bbp_get_reply_id( $reply_id );
 702  
 703          // Show the topic reply log if this is a topic in a reply loop
 704          if ( bbp_is_topic( $reply_id ) ) {
 705              return bbp_get_topic_revision_log( $reply_id );
 706          }
 707  
 708          // Get the reply revision log (out of post meta
 709          $revision_log = bbp_get_reply_raw_revision_log( $reply_id );
 710  
 711          // Check reply and revision log exist
 712          if ( empty( $reply_id ) || empty( $revision_log ) || ! is_array( $revision_log ) ) {
 713              return false;
 714          }
 715  
 716          // Get the actual revisions
 717          $revisions = bbp_get_reply_revisions( $reply_id );
 718          if ( empty( $revisions ) ) {
 719              return false;
 720          }
 721  
 722          $r = "\n\n" . '<ul id="bbp-reply-revision-log-' . esc_attr( $reply_id ) . '" class="bbp-reply-revision-log">' . "\n\n";
 723  
 724          // Loop through revisions
 725          foreach ( (array) $revisions as $revision ) {
 726  
 727              if ( empty( $revision_log[ $revision->ID ] ) ) {
 728                  $author_id = $revision->post_author;
 729                  $reason    = '';
 730              } else {
 731                  $author_id = $revision_log[ $revision->ID ]['author'];
 732                  $reason    = $revision_log[ $revision->ID ]['reason'];
 733              }
 734  
 735              $author = bbp_get_author_link( array( 'size' => 14, 'link_text' => bbp_get_reply_author_display_name( $revision->ID ), 'post_id' => $revision->ID ) );
 736              $since  = bbp_get_time_since( bbp_convert_date( $revision->post_modified ) );
 737  
 738              $r .= "\t" . '<li id="bbp-reply-revision-log-' . esc_attr( $reply_id ) . '-item-' . esc_attr( $revision->ID ) . '" class="bbp-reply-revision-log-item">' . "\n";
 739              if ( ! empty( $reason ) ) {
 740                  $r .= "\t\t" . sprintf( esc_html__( 'This reply was modified %1$s by %2$s. Reason: %3$s', 'bbpress' ), esc_html( $since ), $author, esc_html( $reason ) ) . "\n";
 741              } else {
 742                  $r .= "\t\t" . sprintf( esc_html__( 'This reply was modified %1$s by %2$s.', 'bbpress' ), esc_html( $since ), $author ) . "\n";
 743              }
 744              $r .= "\t" . '</li>' . "\n";
 745  
 746          }
 747  
 748          $r .= "\n" . '</ul>' . "\n\n";
 749  
 750          // Filter & return
 751          return apply_filters( 'bbp_get_reply_revision_log', $r, $reply_id );
 752      }
 753          /**
 754           * Return the raw revision log of the reply
 755           *
 756           * @since 2.0.0 bbPress (r2782)
 757           *
 758           * @param int $reply_id Optional. Reply id
 759           * @return string Raw revision log of the reply
 760           */
 761  		function bbp_get_reply_raw_revision_log( $reply_id = 0 ) {
 762              $reply_id     = bbp_get_reply_id( $reply_id );
 763              $revision_log = get_post_meta( $reply_id, '_bbp_revision_log', true );
 764              $revision_log = empty( $revision_log ) ? array() : $revision_log;
 765  
 766              // Filter & return
 767              return apply_filters( 'bbp_get_reply_raw_revision_log', $revision_log, $reply_id );
 768          }
 769  
 770  /**
 771   * Return the revisions of the reply
 772   *
 773   * @since 2.0.0 bbPress (r2782)
 774   *
 775   * @param int $reply_id Optional. Reply id
 776   * @return string reply revisions
 777   */
 778  function bbp_get_reply_revisions( $reply_id = 0 ) {
 779      $reply_id  = bbp_get_reply_id( $reply_id );
 780      $revisions = wp_get_post_revisions( $reply_id, array( 'order' => 'ASC' ) );
 781  
 782      // Filter & return
 783      return apply_filters( 'bbp_get_reply_revisions', $revisions, $reply_id );
 784  }
 785  
 786  /**
 787   * Return the revision count of the reply
 788   *
 789   * @since 2.0.0 bbPress (r2782)
 790   *
 791   * @param int $reply_id Optional. Reply id
 792   * @param boolean $integer Optional. Whether or not to format the result
 793   * @return string reply revision count
 794   */
 795  function bbp_get_reply_revision_count( $reply_id = 0, $integer = false ) {
 796      $reply_id = bbp_get_reply_id( $reply_id );
 797      $count    = count( bbp_get_reply_revisions( $reply_id ) );
 798      $filter   = ( true === $integer )
 799          ? 'bbp_get_reply_revision_count_int'
 800          : 'bbp_get_reply_revision_count';
 801  
 802      return apply_filters( $filter, $count, $reply_id );
 803  }
 804  
 805  /**
 806   * Output the status of the reply
 807   *
 808   * @since 2.0.0 bbPress (r2667)
 809   *
 810   * @param int $reply_id Optional. Reply id
 811   */
 812  function bbp_reply_status( $reply_id = 0 ) {
 813      echo bbp_get_reply_status( $reply_id );
 814  }
 815      /**
 816       * Return the status of the reply
 817       *
 818       * @since 2.0.0 bbPress (r2667)
 819       *
 820       * @param int $reply_id Optional. Reply id
 821       * @return string Status of reply
 822       */
 823  	function bbp_get_reply_status( $reply_id = 0 ) {
 824          $reply_id = bbp_get_reply_id( $reply_id );
 825  
 826          // Filter & return
 827          return apply_filters( 'bbp_get_reply_status', get_post_status( $reply_id ), $reply_id );
 828      }
 829  
 830  /**
 831   * Return array of public reply statuses.
 832   *
 833   * @since 2.6.0 bbPress (r6705)
 834   *
 835   * @return array
 836   */
 837  function bbp_get_public_reply_statuses() {
 838      $statuses = array(
 839          bbp_get_public_status_id()
 840      );
 841  
 842      // Filter & return
 843      return (array) apply_filters( 'bbp_get_public_reply_statuses', $statuses );
 844  }
 845  
 846  /**
 847   * Return array of non-public reply statuses.
 848   *
 849   * @since 2.6.0 bbPress (r6791)
 850   *
 851   * @return array
 852   */
 853  function bbp_get_non_public_reply_statuses() {
 854      $statuses = array(
 855          bbp_get_trash_status_id(),
 856          bbp_get_spam_status_id(),
 857          bbp_get_pending_status_id()
 858      );
 859  
 860      // Filter & return
 861      return (array) apply_filters( 'bbp_get_non_public_reply_statuses', $statuses );
 862  }
 863  
 864  /**
 865   * Is the reply publicly viewable?
 866   *
 867   * See bbp_get_public_reply_statuses() for public statuses.
 868   *
 869   * @since 2.6.0 bbPress (r6391)
 870   *
 871   * @param int $reply_id Optional. Reply id
 872   * @return bool True if public, false if not.
 873   */
 874  function bbp_is_reply_public( $reply_id = 0 ) {
 875      $reply_id  = bbp_get_reply_id( $reply_id );
 876      $status    = bbp_get_reply_status( $reply_id );
 877      $public    = bbp_get_public_reply_statuses();
 878      $is_public = in_array( $status, $public, true );
 879  
 880      // Filter & return
 881      return (bool) apply_filters( 'bbp_is_reply_public', $is_public, $reply_id );
 882  }
 883  
 884  /**
 885   * Is the reply not spam or deleted?
 886   *
 887   * @since 2.0.0 bbPress (r3496)
 888   *
 889   * @param int $reply_id Optional. Topic id
 890   * @return bool True if published, false if not.
 891   */
 892  function bbp_is_reply_published( $reply_id = 0 ) {
 893      $reply_id     = bbp_get_reply_id( $reply_id );
 894      $status       = bbp_get_public_status_id();
 895      $reply_status = bbp_get_reply_status( $reply_id ) === $status;
 896  
 897      // Filter & return
 898      return (bool) apply_filters( 'bbp_is_reply_published', (bool) $reply_status, $reply_id );
 899  }
 900  
 901  /**
 902   * Is the reply marked as spam?
 903   *
 904   * @since 2.0.0 bbPress (r2740)
 905   *
 906   * @param int $reply_id Optional. Reply id
 907   * @return bool True if spam, false if not.
 908   */
 909  function bbp_is_reply_spam( $reply_id = 0 ) {
 910      $reply_id     = bbp_get_reply_id( $reply_id );
 911      $status       = bbp_get_spam_status_id();
 912      $reply_status = bbp_get_reply_status( $reply_id ) === $status;
 913  
 914      // Filter & return
 915      return (bool) apply_filters( 'bbp_is_reply_spam', (bool) $reply_status, $reply_id );
 916  }
 917  
 918  /**
 919   * Is the reply trashed?
 920   *
 921   * @since 2.0.0 bbPress (r2884)
 922   *
 923   * @param int $reply_id Optional. Topic id
 924   * @return bool True if spam, false if not.
 925   */
 926  function bbp_is_reply_trash( $reply_id = 0 ) {
 927      $reply_id     = bbp_get_reply_id( $reply_id );
 928      $status       = bbp_get_trash_status_id();
 929      $reply_status = bbp_get_reply_status( $reply_id ) === $status;
 930  
 931      // Filter & return
 932      return (bool) apply_filters( 'bbp_is_reply_trash', (bool) $reply_status, $reply_id );
 933  }
 934  
 935  /**
 936   * Is the reply pending?
 937   *
 938   * @since 2.6.0 bbPress (r5507)
 939   *
 940   * @param int $reply_id Optional. Topic id
 941   * @return bool True if pending, false if not.
 942   */
 943  function bbp_is_reply_pending( $reply_id = 0 ) {
 944      $reply_id     = bbp_get_reply_id( $reply_id );
 945      $status       = bbp_get_pending_status_id();
 946      $reply_status = bbp_get_reply_status( $reply_id ) === $status;
 947  
 948      // Filter & return
 949      return (bool) apply_filters( 'bbp_is_reply_pending', (bool) $reply_status, $reply_id );
 950  }
 951  
 952  /**
 953   * Is the reply private?
 954   *
 955   * @since 2.6.0 bbPress (r5507)
 956   *
 957   * @param int $reply_id Optional. Topic id
 958   * @return bool True if private, false if not.
 959   */
 960  function bbp_is_reply_private( $reply_id = 0 ) {
 961      $reply_id     = bbp_get_reply_id( $reply_id );
 962      $status       = bbp_get_private_status_id();
 963      $reply_status = bbp_get_reply_status( $reply_id ) === $status;
 964  
 965      // Filter & return
 966      return (bool) apply_filters( 'bbp_is_reply_private', (bool) $reply_status, $reply_id );
 967  }
 968  
 969  /**
 970   * Is the reply by an anonymous user?
 971   *
 972   * @since 2.0.0 bbPress (r2753)
 973   *
 974   * @param int $reply_id Optional. Reply id
 975   * @return bool True if the post is by an anonymous user, false if not.
 976   */
 977  function bbp_is_reply_anonymous( $reply_id = 0 ) {
 978      $reply_id = bbp_get_reply_id( $reply_id );
 979      $retval   = false;
 980  
 981      if ( ! bbp_get_reply_author_id( $reply_id ) ) {
 982          $retval = true;
 983  
 984      } elseif ( get_post_meta( $reply_id, '_bbp_anonymous_name', true ) ) {
 985          $retval = true;
 986  
 987      } elseif ( get_post_meta( $reply_id, '_bbp_anonymous_email', true ) ) {
 988          $retval = true;
 989      }
 990  
 991      // Filter & return
 992      return (bool) apply_filters( 'bbp_is_reply_anonymous', $retval, $reply_id );
 993  }
 994  
 995  /**
 996   * Deprecated. Use bbp_reply_author_display_name() instead.
 997   *
 998   * Output the author of the reply
 999   *
1000   * @since 2.0.0 bbPress (r2667)
1001   *
1002   * @deprecated 2.5.0 bbPress (r5119)
1003   *
1004   * @param int $reply_id Optional. Reply id
1005   */
1006  function bbp_reply_author( $reply_id = 0 ) {
1007      echo bbp_get_reply_author( $reply_id );
1008  }
1009      /**
1010       * Deprecated. Use bbp_get_reply_author_display_name() instead.
1011       *
1012       * Return the author of the reply
1013       *
1014       * @since 2.0.0 bbPress (r2667)
1015       *
1016       * @deprecated 2.5.0 bbPress (r5119)
1017       *
1018       * @param int $reply_id Optional. Reply id
1019       * @return string Author of reply
1020       */
1021  	function bbp_get_reply_author( $reply_id = 0 ) {
1022          $reply_id = bbp_get_reply_id( $reply_id );
1023  
1024          if ( ! bbp_is_reply_anonymous( $reply_id ) ) {
1025              $author = get_the_author_meta( 'display_name', bbp_get_reply_author_id( $reply_id ) );
1026          } else {
1027              $author = get_post_meta( $reply_id, '_bbp_anonymous_name', true );
1028          }
1029  
1030          // Filter & return
1031          return apply_filters( 'bbp_get_reply_author', $author, $reply_id );
1032      }
1033  
1034  /**
1035   * Output the author ID of the reply
1036   *
1037   * @since 2.0.0 bbPress (r2667)
1038   *
1039   * @param int $reply_id Optional. Reply id
1040   */
1041  function bbp_reply_author_id( $reply_id = 0 ) {
1042      echo bbp_get_reply_author_id( $reply_id );
1043  }
1044      /**
1045       * Return the author ID of the reply
1046       *
1047       * @since 2.0.0 bbPress (r2667)
1048       *
1049       * @param int $reply_id Optional. Reply id
1050       * @return string Author id of reply
1051       */
1052  	function bbp_get_reply_author_id( $reply_id = 0 ) {
1053          $reply_id  = bbp_get_reply_id( $reply_id );
1054          $author_id = get_post_field( 'post_author', $reply_id );
1055  
1056          // Filter & return
1057          return (int) apply_filters( 'bbp_get_reply_author_id', $author_id, $reply_id );
1058      }
1059  
1060  /**
1061   * Output the author display_name of the reply
1062   *
1063   * @since 2.0.0 bbPress (r2667)
1064   *
1065   * @param int $reply_id Optional. Reply id
1066   */
1067  function bbp_reply_author_display_name( $reply_id = 0 ) {
1068      echo bbp_get_reply_author_display_name( $reply_id );
1069  }
1070      /**
1071       * Return the author display_name of the reply
1072       *
1073       * @since 2.0.0 bbPress (r2667)
1074       *
1075       * @param int $reply_id Optional. Reply id
1076       * @return string The display name of the author of the reply
1077       */
1078  	function bbp_get_reply_author_display_name( $reply_id = 0 ) {
1079          $reply_id = bbp_get_reply_id( $reply_id );
1080  
1081          // User is not a guest
1082          if ( ! bbp_is_reply_anonymous( $reply_id ) ) {
1083  
1084              // Get the author ID
1085              $author_id = bbp_get_reply_author_id( $reply_id );
1086  
1087              // Try to get a display name
1088              $author_name = get_the_author_meta( 'display_name', $author_id );
1089  
1090              // Fall back to user login
1091              if ( empty( $author_name ) ) {
1092                  $author_name = get_the_author_meta( 'user_login', $author_id );
1093              }
1094  
1095          // User does not have an account
1096          } else {
1097              $author_name = get_post_meta( $reply_id, '_bbp_anonymous_name', true );
1098          }
1099  
1100          // Fallback if nothing could be found
1101          if ( empty( $author_name ) ) {
1102              $author_name = bbp_get_fallback_display_name( $reply_id );
1103          }
1104  
1105          // Encode possible UTF8 display names
1106          if ( seems_utf8( $author_name ) === false ) {
1107              $author_name = utf8_encode( $author_name );
1108          }
1109  
1110          // Filter & return
1111          return apply_filters( 'bbp_get_reply_author_display_name', $author_name, $reply_id );
1112      }
1113  
1114  /**
1115   * Output the author avatar of the reply
1116   *
1117   * @since 2.0.0 bbPress (r2667)
1118   *
1119   * @param int $reply_id Optional. Reply id
1120   * @param int $size Optional. Size of the avatar. Defaults to 40
1121   */
1122  function bbp_reply_author_avatar( $reply_id = 0, $size = 40 ) {
1123      echo bbp_get_reply_author_avatar( $reply_id, $size );
1124  }
1125      /**
1126       * Return the author avatar of the reply
1127       *
1128       * @since 2.0.0 bbPress (r2667)
1129       *
1130       * @param int $reply_id Optional. Reply id
1131       * @param int $size Optional. Size of the avatar. Defaults to 40
1132       * @return string Avatar of author of the reply
1133       */
1134  	function bbp_get_reply_author_avatar( $reply_id = 0, $size = 40 ) {
1135          $reply_id = bbp_get_reply_id( $reply_id );
1136          if ( ! empty( $reply_id ) ) {
1137              // Check for anonymous user
1138              if ( ! bbp_is_reply_anonymous( $reply_id ) ) {
1139                  $author_avatar = get_avatar( bbp_get_reply_author_id( $reply_id ), $size );
1140              } else {
1141                  $author_avatar = get_avatar( get_post_meta( $reply_id, '_bbp_anonymous_email', true ), $size );
1142              }
1143          } else {
1144              $author_avatar = '';
1145          }
1146  
1147          // Filter & return
1148          return apply_filters( 'bbp_get_reply_author_avatar', $author_avatar, $reply_id, $size );
1149      }
1150  
1151  /**
1152   * Output the author link of the reply
1153   *
1154   * @since 2.0.0 bbPress (r2717)
1155   *
1156   * @param array $args Optional. If it is an integer, it is used as reply id.
1157   */
1158  function bbp_reply_author_link( $args = array() ) {
1159      echo bbp_get_reply_author_link( $args );
1160  }
1161      /**
1162       * Return the author link of the reply
1163       *
1164       * @since 2.0.0 bbPress (r2717)
1165       *
1166       * @param array $args Optional. If an integer, it is used as reply id.
1167       * @return string Author link of reply
1168       */
1169  	function bbp_get_reply_author_link( $args = array() ) {
1170  
1171          // Parse arguments against default values
1172          $r = bbp_parse_args( $args, array(
1173              'post_id'    => 0,
1174              'link_title' => '',
1175              'type'       => 'both',
1176              'size'       => 80,
1177              'sep'        => '',
1178              'show_role'  => false
1179          ), 'get_reply_author_link' );
1180  
1181          // Default return value
1182          $author_link = '';
1183  
1184          // Used as reply_id
1185          $reply_id = is_numeric( $args )
1186              ? bbp_get_reply_id( $args )
1187              : bbp_get_reply_id( $r['post_id'] );
1188  
1189          // Reply ID is good
1190          if ( ! empty( $reply_id ) ) {
1191  
1192              // Get some useful reply information
1193              $author_url = bbp_get_reply_author_url( $reply_id );
1194              $anonymous  = bbp_is_reply_anonymous( $reply_id );
1195  
1196              // Tweak link title if empty
1197              if ( empty( $r['link_title'] ) ) {
1198                  $author = bbp_get_reply_author_display_name( $reply_id );
1199                  $title  = empty( $anonymous )
1200                      ? esc_attr__( "View %s's profile",  'bbpress' )
1201                      : esc_attr__( "Visit %s's website", 'bbpress' );
1202  
1203                  $link_title = sprintf( $title, $author );
1204  
1205              // Use what was passed if not
1206              } else {
1207                  $link_title = $r['link_title'];
1208              }
1209  
1210              // Setup title and author_links array
1211              $author_links = array();
1212              $link_title   = ! empty( $link_title )
1213                  ? ' title="' . esc_attr( $link_title ) . '"'
1214                  : '';
1215  
1216              // Get avatar (unescaped, because HTML)
1217              if ( ( 'avatar' === $r['type'] ) || ( 'both' === $r['type'] ) ) {
1218                  $author_links['avatar'] = bbp_get_reply_author_avatar( $reply_id, $r['size'] );
1219              }
1220  
1221              // Get display name (escaped, because never HTML)
1222              if ( ( 'name' === $r['type'] ) || ( 'both' === $r['type'] ) ) {
1223                  $author_links['name'] = esc_html( bbp_get_reply_author_display_name( $reply_id ) );
1224              }
1225  
1226              // Empty array
1227              $links  = array();
1228              $sprint = '<span %1$s>%2$s</span>';
1229  
1230              // Wrap each link
1231              foreach ( $author_links as $link => $link_text ) {
1232                  $link_class = ' class="bbp-author-' . esc_attr( $link ) . '"';
1233                  $links[]    = sprintf( $sprint, $link_class, $link_text );
1234              }
1235  
1236              // Juggle
1237              $author_links = $links;
1238              unset( $links );
1239  
1240              // Filter sections
1241              $sections    = apply_filters( 'bbp_get_reply_author_links', $author_links, $r, $args );
1242  
1243              // Assemble sections into author link
1244              $author_link = implode( $r['sep'], $sections );
1245  
1246              // Only wrap in link if profile exists
1247              if ( empty( $anonymous ) && bbp_user_has_profile( bbp_get_reply_author_id( $reply_id ) ) ) {
1248                  $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 );
1249              }
1250  
1251              // Role is not linked
1252              if ( true === $r['show_role'] ) {
1253                  $author_link .= bbp_get_reply_author_role( array( 'reply_id' => $reply_id ) );
1254              }
1255          }
1256  
1257          // Filter & return
1258          return apply_filters( 'bbp_get_reply_author_link', $author_link, $r, $args );
1259      }
1260  
1261  /**
1262   * Output the author url of the reply
1263   *
1264   * @since 2.0.0 bbPress (r2667)
1265   *
1266   * @param int $reply_id Optional. Reply id
1267   */
1268  function bbp_reply_author_url( $reply_id = 0 ) {
1269      echo esc_url( bbp_get_reply_author_url( $reply_id ) );
1270  }
1271      /**
1272       * Return the author url of the reply
1273       *
1274       * @since 2.0.0 bbPress (r2667)
1275       *
1276       * @param int $reply_id Optional. Reply id
1277       * @return string Author URL of the reply
1278       */
1279  	function bbp_get_reply_author_url( $reply_id = 0 ) {
1280          $reply_id = bbp_get_reply_id( $reply_id );
1281  
1282          // Check for anonymous user or non-existant user
1283          if ( ! bbp_is_reply_anonymous( $reply_id ) && bbp_user_has_profile( bbp_get_reply_author_id( $reply_id ) ) ) {
1284              $author_url = bbp_get_user_profile_url( bbp_get_reply_author_id( $reply_id ) );
1285          } else {
1286              $author_url = get_post_meta( $reply_id, '_bbp_anonymous_website', true );
1287              if ( empty( $author_url ) ) {
1288                  $author_url = '';
1289              }
1290          }
1291  
1292          // Filter & return
1293          return apply_filters( 'bbp_get_reply_author_url', $author_url, $reply_id );
1294      }
1295  
1296  /**
1297   * Output the reply author email address
1298   *
1299   * @since 2.0.0 bbPress (r3445)
1300   *
1301   * @param int $reply_id Optional. Reply id
1302   */
1303  function bbp_reply_author_email( $reply_id = 0 ) {
1304      echo bbp_get_reply_author_email( $reply_id );
1305  }
1306      /**
1307       * Return the reply author email address
1308       *
1309       * @since 2.0.0 bbPress (r3445)
1310       *
1311       * @param int $reply_id Optional. Reply id
1312       * @return string Reply author email address
1313       */
1314  	function bbp_get_reply_author_email( $reply_id = 0 ) {
1315          $reply_id = bbp_get_reply_id( $reply_id );
1316  
1317          // Not anonymous
1318          if ( ! bbp_is_reply_anonymous( $reply_id ) ) {
1319  
1320              // Use reply author email address
1321              $user_id      = bbp_get_reply_author_id( $reply_id );
1322              $user         = get_userdata( $user_id );
1323              $author_email = ! empty( $user->user_email ) ? $user->user_email : '';
1324  
1325          // Anonymous
1326          } else {
1327  
1328              // Get email from post meta
1329              $author_email = get_post_meta( $reply_id, '_bbp_anonymous_email', true );
1330  
1331              // Sanity check for missing email address
1332              if ( empty( $author_email ) ) {
1333                  $author_email = '';
1334              }
1335          }
1336  
1337          // Filter & return
1338          return apply_filters( 'bbp_get_reply_author_email', $author_email, $reply_id );
1339      }
1340  
1341  /**
1342   * Output the reply author role
1343   *
1344   * @since 2.1.0 bbPress (r3860)
1345   *
1346   * @param array $args Optional.
1347   */
1348  function bbp_reply_author_role( $args = array() ) {
1349      echo bbp_get_reply_author_role( $args );
1350  }
1351      /**
1352       * Return the reply author role
1353       *
1354       * @since 2.1.0 bbPress (r3860)
1355       *
1356       * @param array $args Optional.
1357       * @return string Reply author role
1358       */
1359  	function bbp_get_reply_author_role( $args = array() ) {
1360  
1361          // Parse arguments against default values
1362          $r = bbp_parse_args( $args, array(
1363              'reply_id' => 0,
1364              'class'    => false,
1365              'before'   => '<div class="bbp-author-role">',
1366              'after'    => '</div>'
1367          ), 'get_reply_author_role' );
1368  
1369          $reply_id    = bbp_get_reply_id( $r['reply_id'] );
1370          $role        = bbp_get_user_display_role( bbp_get_reply_author_id( $reply_id ) );
1371  
1372          // Backwards compatibilty with old 'class' argument
1373          if ( ! empty( $r['class'] ) ) {
1374              $author_role = sprintf( '%1$s<div class="%2$s">%3$s</div>%4$s', $r['before'], esc_attr( $r['class'] ), esc_html( $role ), $r['after'] );
1375  
1376          // Simpler before & after arguments
1377          // https://bbpress.trac.wordpress.org/ticket/2557
1378          } else {
1379              $author_role = $r['before'] . $role . $r['after'];
1380          }
1381  
1382          // Filter & return
1383          return apply_filters( 'bbp_get_reply_author_role', $author_role, $r, $args );
1384      }
1385  
1386  /**
1387   * Output the topic title a reply belongs to
1388   *
1389   * @since 2.0.0 bbPress (r2553)
1390   *
1391   * @param int $reply_id Optional. Reply id
1392   */
1393  function bbp_reply_topic_title( $reply_id = 0 ) {
1394      echo bbp_get_reply_topic_title( $reply_id );
1395  }
1396      /**
1397       * Return the topic title a reply belongs to
1398       *
1399       * @since 2.0.0 bbPress (r2553)
1400       *
1401       * @param int $reply_id Optional. Reply id
1402       * @return string The topic title of the reply
1403       */
1404  	function bbp_get_reply_topic_title( $reply_id = 0 ) {
1405          $reply_id = bbp_get_reply_id( $reply_id );
1406          $topic_id = bbp_get_reply_topic_id( $reply_id );
1407  
1408          // Filter & return
1409          return apply_filters( 'bbp_get_reply_topic_title', bbp_get_topic_title( $topic_id ), $reply_id );
1410      }
1411  
1412  /**
1413   * Output the topic id a reply belongs to
1414   *
1415   * @since 2.0.0 bbPress (r2553)
1416   *
1417   * @param int $reply_id Optional. Reply id
1418   */
1419  function bbp_reply_topic_id( $reply_id = 0 ) {
1420      echo bbp_get_reply_topic_id( $reply_id );
1421  }
1422      /**
1423       * Return the topic id a reply belongs to
1424       *
1425       * @since 2.0.0 bbPress (r2553)
1426       *
1427       * @param int $reply_id Optional. Reply id
1428       * @return int The topic id of the reply
1429       */
1430  	function bbp_get_reply_topic_id( $reply_id = 0 ) {
1431          $reply_id = bbp_get_reply_id( $reply_id );
1432          $topic_id = get_post_field( 'post_parent', $reply_id );
1433  
1434          // Meta-data fallback
1435          if ( empty( $topic_id ) ) {
1436              $topic_id = get_post_meta( $reply_id, '_bbp_topic_id', true );
1437          }
1438  
1439          // Filter
1440          if ( ! empty( $topic_id ) ) {
1441              $topic_id = bbp_get_topic_id( $topic_id );
1442          }
1443  
1444          // Filter & return
1445          return (int) apply_filters( 'bbp_get_reply_topic_id', (int) $topic_id, $reply_id );
1446      }
1447  
1448  /**
1449   * Output the forum id a reply belongs to
1450   *
1451   * @since 2.0.0 bbPress (r2679)
1452   *
1453   * @param int $reply_id Optional. Reply id
1454   */
1455  function bbp_reply_forum_id( $reply_id = 0 ) {
1456      echo bbp_get_reply_forum_id( $reply_id );
1457  }
1458      /**
1459       * Return the forum id a reply belongs to
1460       *
1461       * @since 2.0.0 bbPress (r2679)
1462       *
1463       * @param int $reply_id Optional. Reply id
1464       *                        id and reply id
1465       * @return int The forum id of the reply
1466       */
1467  	function bbp_get_reply_forum_id( $reply_id = 0 ) {
1468          $reply_id = bbp_get_reply_id( $reply_id );
1469          $forum_id = get_post_field( 'post_parent', bbp_get_reply_topic_id( $reply_id ) );
1470  
1471          // Meta-data fallback
1472          if ( empty( $forum_id ) ) {
1473              $forum_id = get_post_meta( $reply_id, '_bbp_forum_id', true );
1474          }
1475  
1476          // Filter
1477          if ( ! empty( $forum_id ) ) {
1478              $forum_id = bbp_get_forum_id( $forum_id );
1479          }
1480  
1481          // Filter & return
1482          return (int) apply_filters( 'bbp_get_reply_forum_id', $forum_id, $reply_id );
1483      }
1484  
1485  /**
1486   * Output the ancestor reply id of a reply
1487   *
1488   * @since 2.4.0 bbPress (r4944)
1489   *
1490   * @param int $reply_id Optional. Reply id
1491   */
1492  function bbp_reply_ancestor_id( $reply_id = 0 ) {
1493      echo bbp_get_reply_ancestor_id( $reply_id );
1494  }
1495      /**
1496       * Return the ancestor reply id of a reply
1497       *
1498       * @since 2.4.0 bbPress (r4944)
1499       *
1500       * @param in $reply_id Reply id
1501       */
1502  	function bbp_get_reply_ancestor_id( $reply_id = 0 ) {
1503  
1504          // Validation
1505          $reply_id = bbp_get_reply_id( $reply_id );
1506          if ( empty( $reply_id ) ) {
1507              return false;
1508          }
1509  
1510          // Find highest reply ancestor
1511          $ancestor_id = $reply_id;
1512          while ( $parent_id = bbp_get_reply_to( $ancestor_id ) ) {
1513              if ( empty( $parent_id ) || ( $parent_id === $ancestor_id ) || ( bbp_get_reply_topic_id( $reply_id ) === $parent_id ) || ( $parent_id === $reply_id ) ) {
1514                  break;
1515              }
1516              $ancestor_id = $parent_id;
1517          }
1518  
1519          return (int) $ancestor_id;
1520      }
1521  
1522  /**
1523   * Output the reply to id of a reply
1524   *
1525   * @since 2.4.0 bbPress (r4944)
1526   *
1527   * @param int $reply_id Optional. Reply id
1528   */
1529  function bbp_reply_to( $reply_id = 0 ) {
1530      echo bbp_get_reply_to( $reply_id );
1531  }
1532      /**
1533       * Return the reply to id of a reply
1534       *
1535        * @since 2.4.0 bbPress (r4944)
1536       *
1537       * @param int $reply_id Optional. Reply id
1538       * @return int The parent reply id of the reply
1539       */
1540  	function bbp_get_reply_to( $reply_id = 0 ) {
1541  
1542          // Assume there is no reply_to set
1543          $reply_to = 0;
1544  
1545          // Check that reply_id is valid
1546          $reply_id = bbp_get_reply_id( $reply_id );
1547  
1548          // Get reply_to value
1549          if ( ! empty( $reply_id ) ) {
1550              $reply_to = (int) get_post_meta( $reply_id, '_bbp_reply_to', true );
1551          }
1552  
1553          // Filter & return
1554          return (int) apply_filters( 'bbp_get_reply_to', $reply_to, $reply_id );
1555      }
1556  
1557  /**
1558   * Output the link for the reply to
1559   *
1560   * @since 2.4.0 bbPress (r4944)
1561   *
1562   * @param array $args
1563   */
1564  function bbp_reply_to_link( $args = array() ) {
1565      echo bbp_get_reply_to_link( $args );
1566  }
1567  
1568      /**
1569       * Return the link for a reply to a reply
1570       *
1571       * @since 2.4.0 bbPress (r4944)
1572       *
1573       * @param array $args Arguments
1574       * @return string Link for a reply to a reply
1575       */
1576  	function bbp_get_reply_to_link( $args = array() ) {
1577  
1578          // Parse arguments against default values
1579          $r = bbp_parse_args( $args, array(
1580              'id'           => 0,
1581              'link_before'  => '',
1582              'link_after'   => '',
1583              'reply_text'   => esc_html_x( 'Reply', 'verb', 'bbpress' ),
1584              'depth'        => 0,
1585              'add_below'    => 'post',
1586              'respond_id'   => 'new-reply-' . bbp_get_topic_id(),
1587          ), 'get_reply_to_link' );
1588  
1589          // Get the reply to use it's ID and post_parent
1590          $reply    = bbp_get_reply( $r['id'] );
1591          $topic_id = bbp_get_reply_topic_id( $reply->ID );
1592  
1593          // Bail if no reply or user cannot reply
1594          if ( empty( $reply ) || empty( $topic_id ) || bbp_is_single_reply() || ! bbp_current_user_can_access_create_reply_form() ) {
1595              return;
1596          }
1597  
1598          // Build the URI and return value
1599          $uri = remove_query_arg( array( 'bbp_reply_to' ) );
1600          $uri = add_query_arg( array( 'bbp_reply_to' => $reply->ID ) );
1601          $uri = wp_nonce_url( $uri, 'respond_id_' . $reply->ID );
1602          $uri = $uri . '#new-post';
1603  
1604          // Only add onclick if replies are threaded
1605          if ( bbp_thread_replies() ) {
1606  
1607              // Array of classes to pass to moveForm
1608              $move_form = array(
1609                  $r['add_below'] . '-' . $reply->ID,
1610                  $reply->ID,
1611                  $r['respond_id'],
1612                  $reply->post_parent
1613              );
1614  
1615              // Build the onclick
1616              $onclick  = ' onclick="return addReply.moveForm(\'' . implode( "','", $move_form ) . '\');"';
1617  
1618          // No onclick if replies are not threaded
1619          } else {
1620              $onclick  = '';
1621          }
1622  
1623          // Add $uri to the array, to be passed through the filter
1624          $r['uri'] = $uri;
1625          $retval   = $r['link_before'] . '<a role="button" href="' . esc_url( $r['uri'] ) . '" class="bbp-reply-to-link"' . $onclick . '>' . $r['reply_text'] . '</a>' . $r['link_after'];
1626  
1627          // Filter & return
1628          return apply_filters( 'bbp_get_reply_to_link', $retval, $r, $args );
1629      }
1630  
1631  /**
1632   * Output the reply to a reply cancellation link
1633   *
1634   * @since 2.4.0 bbPress (r4944)
1635   */
1636  function bbp_cancel_reply_to_link( $text = '' ) {
1637      echo bbp_get_cancel_reply_to_link( $text );
1638  }
1639      /**
1640       * Return the cancellation link for a reply to a reply
1641       *
1642       * @since 2.4.0 bbPress (r4944)
1643       *
1644       * @param string $text The cancel text
1645       * @return string The cancellation link
1646       */
1647  	function bbp_get_cancel_reply_to_link( $text = '' ) {
1648  
1649          // Bail if not hierarchical or editing a reply
1650          if ( ! bbp_thread_replies() || bbp_is_reply_edit() ) {
1651              return;
1652          }
1653  
1654          // Set default text
1655          if ( empty( $text ) ) {
1656              $text = esc_html__( 'Cancel', 'bbpress' );
1657          }
1658  
1659          // Replying to...
1660          $reply_to = isset( $_GET['bbp_reply_to'] )
1661              ? (int) $_GET['bbp_reply_to']
1662              : 0;
1663  
1664          // Set visibility
1665          $style  = ! empty( $reply_to ) ? '' : ' style="display:none;"';
1666          $link   = remove_query_arg( array( 'bbp_reply_to', '_wpnonce' ) ) . "#post-{$reply_to}";
1667          $retval = sprintf( '<a href="%1$s" id="bbp-cancel-reply-to-link"%2$s>%3$s</a>', esc_url( $link ), $style, esc_html( $text ) );
1668  
1669          // Filter & return
1670          return apply_filters( 'bbp_get_cancel_reply_to_link', $retval, $link, $text );
1671      }
1672  
1673  /**
1674   * Output the numeric position of a reply within a topic
1675   *
1676   * @since 2.0.0 bbPress (r2984)
1677   *
1678   * @param int $reply_id Optional. Reply id
1679   * @param int $topic_id Optional. Topic id
1680   */
1681  function bbp_reply_position( $reply_id = 0, $topic_id = 0 ) {
1682      echo bbp_get_reply_position( $reply_id, $topic_id );
1683  }
1684      /**
1685       * Return the numeric position of a reply within a topic
1686       *
1687       * @since 2.0.0 bbPress (r2984)
1688       *
1689       * @param int $reply_id Optional. Reply id
1690       * @param int $topic_id Optional. Topic id
1691       * @return int Reply position
1692       */
1693  	function bbp_get_reply_position( $reply_id = 0, $topic_id = 0 ) {
1694  
1695          // Get required data
1696          $reply_id       = bbp_get_reply_id( $reply_id );
1697          $reply_position = get_post_field( 'menu_order', $reply_id );
1698  
1699          // Reply doesn't have a position so get the raw value
1700          if ( empty( $reply_position ) ) {
1701  
1702              // Get topic ID
1703              $topic_id = ! empty( $topic_id )
1704                  ? bbp_get_topic_id( $topic_id )
1705                  : bbp_get_reply_topic_id( $reply_id );
1706  
1707              // Post is not the topic
1708              if ( $reply_id !== $topic_id ) {
1709                  $reply_position = bbp_get_reply_position_raw( $reply_id, $topic_id );
1710  
1711                  // Update the reply position in the posts table so we'll never have
1712                  // to hit the DB again.
1713                  if ( ! empty( $reply_position ) ) {
1714                      bbp_update_reply_position( $reply_id, $reply_position );
1715                  }
1716  
1717              // Topic's position is always 0
1718              } else {
1719                  $reply_position = 0;
1720              }
1721          }
1722  
1723          // Bump the position by one if the topic is included in the reply loop
1724          if ( ! bbp_show_lead_topic() ) {
1725              $reply_position++;
1726          }
1727  
1728          // Filter & return
1729          return (int) apply_filters( 'bbp_get_reply_position', $reply_position, $reply_id, $topic_id );
1730      }
1731  
1732  /** Reply Admin Links *********************************************************/
1733  
1734  /**
1735   * Output admin links for reply
1736   *
1737   * @since 2.0.0 bbPress (r2667)
1738   *
1739   * @param array $args See {@link bbp_get_reply_admin_links()}
1740   */
1741  function bbp_reply_admin_links( $args = array() ) {
1742      echo bbp_get_reply_admin_links( $args );
1743  }
1744      /**
1745       * Return admin links for reply
1746       *
1747       * @since 2.0.0 bbPress (r2667)
1748       *
1749       * @param array $args This function supports these arguments:
1750       *  - id: Optional. Reply id
1751       *  - before: HTML before the links. Defaults to
1752       *             '<span class="bbp-admin-links">'
1753       *  - after: HTML after the links. Defaults to '</span>'
1754       *  - sep: Separator. Defaults to ' | '
1755       *  - links: Array of the links to display. By default, edit, trash,
1756       *            spam, reply move, and topic split links are displayed
1757       * @return string Reply admin links
1758       */
1759  	function bbp_get_reply_admin_links( $args = array() ) {
1760  
1761          // Parse arguments against default values
1762          $r = bbp_parse_args( $args, array(
1763              'id'     => 0,
1764              'before' => '<span class="bbp-admin-links">',
1765              'after'  => '</span>',
1766              'sep'    => ' | ',
1767              'links'  => array()
1768          ), 'get_reply_admin_links' );
1769  
1770          $r['id'] = bbp_get_reply_id( $r['id'] );
1771  
1772          // If post is a topic, return the topic admin links instead
1773          if ( bbp_is_topic( $r['id'] ) ) {
1774              return bbp_get_topic_admin_links( $args );
1775          }
1776  
1777          // If post is not a reply, return
1778          if ( ! bbp_is_reply( $r['id'] ) ) {
1779              return;
1780          }
1781  
1782          // If topic is trashed, do not show admin links
1783          if ( bbp_is_topic_trash( bbp_get_reply_topic_id( $r['id'] ) ) ) {
1784              return;
1785          }
1786  
1787          // If no links were passed, default to the standard
1788          if ( empty( $r['links'] ) ) {
1789              $r['links'] = apply_filters( 'bbp_reply_admin_links', array(
1790                  'edit'    => bbp_get_reply_edit_link   ( $r ),
1791                  'move'    => bbp_get_reply_move_link   ( $r ),
1792                  'split'   => bbp_get_topic_split_link  ( $r ),
1793                  'trash'   => bbp_get_reply_trash_link  ( $r ),
1794                  'spam'    => bbp_get_reply_spam_link   ( $r ),
1795                  'approve' => bbp_get_reply_approve_link( $r ),
1796                  'reply'   => bbp_get_reply_to_link     ( $r )
1797              ), $r['id'] );
1798          }
1799  
1800          // See if links need to be unset
1801          $reply_status = bbp_get_reply_status( $r['id'] );
1802          if ( in_array( $reply_status, array( bbp_get_spam_status_id(), bbp_get_trash_status_id(), bbp_get_pending_status_id() ), true ) ) {
1803  
1804              // Spam link shouldn't be visible on trashed topics
1805              if ( bbp_get_trash_status_id() === $reply_status ) {
1806                  unset( $r['links']['spam'] );
1807  
1808              // Trash link shouldn't be visible on spam topics
1809              } elseif ( bbp_get_spam_status_id() === $reply_status ) {
1810                  unset( $r['links']['trash'] );
1811              }
1812          }
1813  
1814          // Process the admin links
1815          $links  = implode( $r['sep'], array_filter( $r['links'] ) );
1816          $retval = $r['before'] . $links . $r['after'];
1817  
1818          // Filter & return
1819          return apply_filters( 'bbp_get_reply_admin_links', $retval, $r, $args );
1820      }
1821  
1822  /**
1823   * Output the edit link of the reply
1824   *
1825   * @since 2.0.0 bbPress (r2740)
1826   *
1827   * @param array $args See {@link bbp_get_reply_edit_link()}
1828   */
1829  function bbp_reply_edit_link( $args = array() ) {
1830      echo bbp_get_reply_edit_link( $args );
1831  }
1832  
1833      /**
1834       * Return the edit link of the reply
1835       *
1836       * @since 2.0.0 bbPress (r2740)
1837       *
1838       * @param array $args This function supports these arguments:
1839       *  - id: Reply id
1840       *  - link_before: HTML before the link
1841       *  - link_after: HTML after the link
1842       *  - edit_text: Edit text. Defaults to 'Edit'
1843       * @return string Reply edit link
1844       */
1845  	function bbp_get_reply_edit_link( $args = array() ) {
1846  
1847          // Parse arguments against default values
1848          $r = bbp_parse_args( $args, array(
1849              'id'           => 0,
1850              'link_before'  => '',
1851              'link_after'   => '',
1852              'edit_text'    => esc_html__( 'Edit', 'bbpress' )
1853          ), 'get_reply_edit_link' );
1854  
1855          // Get reply
1856          $reply = bbp_get_reply( $r['id'] );
1857  
1858          // Bypass check if user has caps
1859          if ( ! current_user_can( 'edit_others_replies' ) ) {
1860  
1861              // User cannot edit or it is past the lock time
1862              if ( empty( $reply ) || ! current_user_can( 'edit_reply', $reply->ID ) || bbp_past_edit_lock( $reply->post_date_gmt ) ) {
1863                  return;
1864              }
1865          }
1866  
1867          // Get uri
1868          $uri = bbp_get_reply_edit_url( $r['id'] );
1869  
1870          // Bail if no uri
1871          if ( empty( $uri ) ) {
1872              return;
1873          }
1874  
1875          $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" class="bbp-reply-edit-link">' . $r['edit_text'] . '</a>' . $r['link_after'];
1876  
1877          // Filter & return
1878          return apply_filters( 'bbp_get_reply_edit_link', $retval, $r, $args );
1879      }
1880  
1881  /**
1882   * Output URL to the reply edit page
1883   *
1884   * @since 2.0.0 bbPress (r2753)
1885   *
1886   * @param int $reply_id Optional. Reply id
1887   */
1888  function bbp_reply_edit_url( $reply_id = 0 ) {
1889      echo esc_url( bbp_get_reply_edit_url( $reply_id ) );
1890  }
1891      /**
1892       * Return URL to the reply edit page
1893       *
1894       * @since 2.0.0 bbPress (r2753)
1895       *
1896       * @param int $reply_id Optional. Reply id
1897       * @return string Reply edit url
1898       */
1899  	function bbp_get_reply_edit_url( $reply_id = 0 ) {
1900  
1901          // Bail if no reply
1902          $reply = bbp_get_reply( $reply_id );
1903          if ( empty( $reply ) ) {
1904              return;
1905          }
1906  
1907          $reply_link = bbp_remove_view_all( bbp_get_reply_permalink( $reply_id ) );
1908  
1909          // Pretty permalinks, previously used `bbp_use_pretty_urls()`
1910          // https://bbpress.trac.wordpress.org/ticket/3054
1911          if ( false === strpos( $reply_link, '?' ) ) {
1912              $url = trailingslashit( $reply_link ) . bbp_get_edit_rewrite_id();
1913              $url = user_trailingslashit( $url );
1914  
1915          // Unpretty permalinks
1916          } else {
1917              $url = add_query_arg( array(
1918                  bbp_get_reply_post_type() => $reply->post_name,
1919                  bbp_get_edit_rewrite_id() => '1'
1920              ), $reply_link );
1921          }
1922  
1923          // Maybe add view all
1924          $url = bbp_add_view_all( $url );
1925  
1926          // Filter & return
1927          return apply_filters( 'bbp_get_reply_edit_url', $url, $reply_id );
1928      }
1929  
1930  /**
1931   * Output the trash link of the reply
1932   *
1933   * @since 2.0.0 bbPress (r2740)
1934   *
1935   * @param array $args See {@link bbp_get_reply_trash_link()}
1936   */
1937  function bbp_reply_trash_link( $args = array() ) {
1938      echo bbp_get_reply_trash_link( $args );
1939  }
1940  
1941      /**
1942       * Return the trash link of the reply
1943       *
1944       * @since 2.0.0 bbPress (r2740)
1945       *
1946       * @param array $args This function supports these arguments:
1947       *  - id: Reply id
1948       *  - link_before: HTML before the link
1949       *  - link_after: HTML after the link
1950       *  - sep: Separator
1951       *  - trash_text: Trash text
1952       *  - restore_text: Restore text
1953       *  - delete_text: Delete text
1954       * @return string Reply trash link
1955       */
1956  	function bbp_get_reply_trash_link( $args = array() ) {
1957  
1958          // Parse arguments against default values
1959          $r = bbp_parse_args( $args, array(
1960              'id'           => 0,
1961              'link_before'  => '',
1962              'link_after'   => '',
1963              'sep'          => ' | ',
1964              'trash_text'   => esc_html__( 'Trash',   'bbpress' ),
1965              'restore_text' => esc_html__( 'Restore', 'bbpress' ),
1966              'delete_text'  => esc_html__( 'Delete',  'bbpress' )
1967          ), 'get_reply_trash_link' );
1968  
1969          // Get reply
1970          $reply = bbp_get_reply( $r['id'] );
1971  
1972          // Bail if no reply or current user cannot delete
1973          if ( empty( $reply ) || ! current_user_can( 'delete_reply', $reply->ID ) ) {
1974              return;
1975          }
1976  
1977          $actions    = array();
1978          $trash_days = bbp_get_trash_days( bbp_get_reply_post_type() );
1979  
1980          // Trashed
1981          if ( bbp_is_reply_trash( $reply->ID ) ) {
1982              $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_reply_trash', 'sub_action' => 'untrash', 'reply_id' => $reply->ID ) ), 'untrash-' . $reply->post_type . '_' . $reply->ID ) ) . '" class="bbp-reply-restore-link">' . $r['restore_text'] . '</a>';
1983  
1984          // Trash
1985          } elseif ( ! empty( $trash_days ) ) {
1986              $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_reply_trash', 'sub_action' => 'trash',   'reply_id' => $reply->ID ) ), 'trash-'   . $reply->post_type . '_' . $reply->ID ) ) . '" class="bbp-reply-trash-link">'   . $r['trash_text']   . '</a>';
1987          }
1988  
1989          // No trash
1990          if ( bbp_is_reply_trash( $reply->ID ) || empty( $trash_days ) ) {
1991              $actions['delete']  = '<a title="' . esc_attr__( 'Delete this item permanently',     'bbpress' ) . '" href="' . esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'bbp_toggle_reply_trash', 'sub_action' => 'delete',  'reply_id' => $reply->ID ) ), 'delete-'  . $reply->post_type . '_' . $reply->ID ) ) . '" onclick="return confirm(\'' . esc_js( __( 'Are you sure you want to delete that permanently?', 'bbpress' ) ) . '\' );" class="bbp-reply-delete-link">' . $r['delete_text'] . '</a>';
1992          }
1993  
1994          // Process the admin links
1995          $retval = $r['link_before'] . implode( $r['sep'], $actions ) . $r['link_after'];
1996  
1997          // Filter & return
1998          return apply_filters( 'bbp_get_reply_trash_link', $retval, $r, $args );
1999      }
2000  
2001  /**
2002   * Output the spam link of the reply
2003   *
2004   * @since 2.0.0 bbPress (r2740)
2005   *
2006   * @param array $args See {@link bbp_get_reply_spam_link()}
2007   */
2008  function bbp_reply_spam_link( $args = array() ) {
2009      echo bbp_get_reply_spam_link( $args );
2010  }
2011  
2012      /**
2013       * Return the spam link of the reply
2014       *
2015       * @since 2.0.0 bbPress (r2740)
2016       *
2017       * @param array $args This function supports these arguments:
2018       *  - id: Reply id
2019       *  - link_before: HTML before the link
2020       *  - link_after: HTML after the link
2021       *  - spam_text: Spam text
2022       *  - unspam_text: Unspam text
2023       * @return string Reply spam link
2024       */
2025  	function bbp_get_reply_spam_link( $args = array() ) {
2026  
2027          // Parse arguments against default values
2028          $r = bbp_parse_args( $args, array(
2029              'id'           => 0,
2030              'link_before'  => '',
2031              'link_after'   => '',
2032              'spam_text'    => esc_html__( 'Spam',   'bbpress' ),
2033              'unspam_text'  => esc_html__( 'Unspam', 'bbpress' )
2034          ), 'get_reply_spam_link' );
2035  
2036          // Get reply
2037          $reply = bbp_get_reply( $r['id'] );
2038  
2039          // Bail if no reply or current user cannot moderate
2040          if ( empty( $reply ) || ! current_user_can( 'moderate', $reply->ID ) ) {
2041              return;
2042          }
2043  
2044          $display = bbp_is_reply_spam( $reply->ID ) ? $r['unspam_text'] : $r['spam_text'];
2045          $uri     = add_query_arg( array( 'action' => 'bbp_toggle_reply_spam', 'reply_id' => $reply->ID ) );
2046          $uri     = wp_nonce_url( $uri, 'spam-reply_' . $reply->ID );
2047          $retval  = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" class="bbp-reply-spam-link">' . $display . '</a>' . $r['link_after'];
2048  
2049          // Filter & return
2050          return apply_filters( 'bbp_get_reply_spam_link', $retval, $r, $args );
2051      }
2052  
2053  /**
2054   * Move reply link
2055   *
2056   * Output the move link of the reply
2057   *
2058   * @since 2.3.0 bbPress (r4521)
2059   *
2060   * @param array $args See {@link bbp_get_reply_move_link()}
2061   */
2062  function bbp_reply_move_link( $args = array() ) {
2063      echo bbp_get_reply_move_link( $args );
2064  }
2065  
2066      /**
2067       * Get move reply link
2068       *
2069       * Return the move link of the reply
2070       *
2071       * @since 2.3.0 bbPress (r4521)
2072       *
2073       * @param array $args This function supports these arguments:
2074       *  - id: Reply id
2075       *  - link_before: HTML before the link
2076       *  - link_after: HTML after the link
2077       *  - move_text: Move text
2078       *  - move_title: Move title attribute
2079       * @return string Reply move link
2080       */
2081  	function bbp_get_reply_move_link( $args = array() ) {
2082  
2083          // Parse arguments against default values
2084          $r = bbp_parse_args( $args, array(
2085              'id'          => 0,
2086              'link_before' => '',
2087              'link_after'  => '',
2088              'split_text'  => esc_html__( 'Move',            'bbpress' ),
2089              'split_title' => esc_attr__( 'Move this reply', 'bbpress' )
2090          ), 'get_reply_move_link' );
2091  
2092          // Get IDs
2093          $reply_id = bbp_get_reply_id( $r['id'] );
2094          $topic_id = bbp_get_reply_topic_id( $reply_id );
2095  
2096          // Bail if no reply ID or user cannot moderate
2097          if ( empty( $reply_id ) || ! current_user_can( 'moderate', $topic_id ) ) {
2098              return;
2099          }
2100  
2101          $uri = add_query_arg( array(
2102              'action'   => 'move',
2103              'reply_id' => $reply_id
2104          ), bbp_get_reply_edit_url( $reply_id ) );
2105  
2106          $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" title="' . $r['split_title'] . '" class="bbp-reply-move-link">' . $r['split_text'] . '</a>' . $r['link_after'];
2107  
2108          // Filter & return
2109          return apply_filters( 'bbp_get_reply_move_link', $retval, $r, $args );
2110      }
2111  
2112  /**
2113   * Split topic link
2114   *
2115   * Output the split link of the topic (but is bundled with each reply)
2116   *
2117   * @since 2.0.0 bbPress (r2756)
2118   *
2119   * @param array $args See {@link bbp_get_topic_split_link()}
2120   */
2121  function bbp_topic_split_link( $args = array() ) {
2122      echo bbp_get_topic_split_link( $args );
2123  }
2124  
2125      /**
2126       * Get split topic link
2127       *
2128       * Return the split link of the topic (but is bundled with each reply)
2129       *
2130       * @since 2.0.0 bbPress (r2756)
2131       *
2132       * @param array $args This function supports these arguments:
2133       *  - id: Reply id
2134       *  - link_before: HTML before the link
2135       *  - link_after: HTML after the link
2136       *  - split_text: Split text
2137       *  - split_title: Split title attribute
2138       * @return string Topic split link
2139       */
2140  	function bbp_get_topic_split_link( $args = array() ) {
2141  
2142          // Parse arguments against default values
2143          $r = bbp_parse_args( $args, array(
2144              'id'          => 0,
2145              'link_before' => '',
2146              'link_after'  => '',
2147              'split_text'  => esc_html__( 'Split',                           'bbpress' ),
2148              'split_title' => esc_attr__( 'Split the topic from this reply', 'bbpress' )
2149          ), 'get_topic_split_link' );
2150  
2151          // Get IDs
2152          $reply_id = bbp_get_reply_id( $r['id'] );
2153          $topic_id = bbp_get_reply_topic_id( $reply_id );
2154  
2155          // Bail if no reply/topic ID, or user cannot moderate
2156          if ( empty( $reply_id ) || empty( $topic_id ) || ! current_user_can( 'moderate', $topic_id ) ) {
2157              return;
2158          }
2159  
2160          $uri = add_query_arg( array(
2161              'action'   => 'split',
2162              'reply_id' => $reply_id
2163          ), bbp_get_topic_edit_url( $topic_id ) );
2164  
2165          $retval = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" title="' . $r['split_title'] . '" class="bbp-topic-split-link">' . $r['split_text'] . '</a>' . $r['link_after'];
2166  
2167          // Filter & return
2168          return apply_filters( 'bbp_get_topic_split_link', $retval, $r, $args );
2169      }
2170  
2171  /**
2172   * Output the approve link of the reply
2173   *
2174   * @since 2.6.0 bbPress (r5507)
2175   *
2176   * @param array $args See {@link bbp_get_reply_approve_link()}
2177   */
2178  function bbp_reply_approve_link( $args = array() ) {
2179      echo bbp_get_reply_approve_link( $args );
2180  }
2181  
2182      /**
2183       * Return the approve link of the reply
2184       *
2185       * @since 2.6.0 bbPress (r5507)
2186       *
2187       * @param array $args This function supports these args:
2188       *  - id: Optional. Reply id
2189       *  - link_before: Before the link
2190       *  - link_after: After the link
2191       *  - sep: Separator between links
2192       *  - approve_text: Approve text
2193       *  - unapprove_text: Unapprove text
2194       * @return string Reply approve link
2195       */
2196  	function bbp_get_reply_approve_link( $args = array() ) {
2197  
2198          // Parse arguments against default values
2199          $r = bbp_parse_args( $args, array(
2200              'id'             => 0,
2201              'link_before'    => '',
2202              'link_after'     => '',
2203              'sep'            => ' | ',
2204              'approve_text'   => _x( 'Approve',   'Pending Status', 'bbpress' ),
2205              'unapprove_text' => _x( 'Unapprove', 'Pending Status', 'bbpress' )
2206          ), 'get_reply_approve_link' );
2207  
2208          // Get reply
2209          $reply = bbp_get_reply( $r['id'] );
2210  
2211          // Bail if no reply or current user cannot moderate
2212          if ( empty( $reply ) || ! current_user_can( 'moderate', $reply->ID ) ) {
2213              return;
2214          }
2215  
2216          $display = bbp_is_reply_pending( $reply->ID ) ? $r['approve_text'] : $r['unapprove_text'];
2217          $uri     = add_query_arg( array( 'action' => 'bbp_toggle_reply_approve', 'reply_id' => $reply->ID ) );
2218          $uri     = wp_nonce_url( $uri, 'approve-reply_' . $reply->ID );
2219          $retval  = $r['link_before'] . '<a href="' . esc_url( $uri ) . '" class="bbp-reply-approve-link">' . $display . '</a>' . $r['link_after'];
2220  
2221          // Filter & return
2222          return apply_filters( 'bbp_get_reply_approve_link', $retval, $r, $args );
2223      }
2224  
2225  /**
2226   * Output the row class of a reply
2227   *
2228   * @since 2.0.0 bbPress (r2678)
2229   *
2230   * @param int $reply_id Optional. Reply ID
2231   * @param array Extra classes you can pass when calling this function
2232   */
2233  function bbp_reply_class( $reply_id = 0, $classes = array() ) {
2234      echo bbp_get_reply_class( $reply_id, $classes );
2235  }
2236      /**
2237       * Return the row class of a reply
2238       *
2239       * @since 2.0.0 bbPress (r2678)
2240       *
2241       * @param int $reply_id Optional. Reply ID
2242       * @param array Extra classes you can pass when calling this function
2243       * @return string Row class of the reply
2244       */
2245  	function bbp_get_reply_class( $reply_id = 0, $classes = array() ) {
2246          $bbp       = bbpress();
2247          $reply_id  = bbp_get_reply_id( $reply_id );
2248          $topic_id  = bbp_get_reply_topic_id( $reply_id );
2249          $forum_id  = bbp_get_reply_forum_id( $reply_id );
2250          $author_id = bbp_get_reply_author_id( $reply_id );
2251          $reply_pos = bbp_get_reply_position( $reply_id, true );
2252          $classes   = array_filter( (array) $classes );
2253          $count     = isset( $bbp->reply_query->current_post )
2254              ? (int) $bbp->reply_query->current_post
2255              : 1;
2256  
2257          //  Stripes
2258          $even_odd = ( $count % 2 )
2259              ? 'even'
2260              : 'odd';
2261  
2262          // Forum moderator replied to topic
2263          $forum_moderator = ( bbp_is_user_forum_moderator( $author_id, $forum_id ) === $author_id )
2264              ? 'forum-mod'
2265              : '';
2266  
2267          // Topic author replied to others
2268          $topic_author = ( bbp_get_topic_author_id( $topic_id ) === $author_id )
2269              ? 'topic-author'
2270              : '';
2271  
2272          // Get reply classes
2273          $reply_classes = array(
2274              'loop-item-'          . $count,
2275              'user-id-'            . $author_id,
2276              'bbp-parent-forum-'   . $forum_id,
2277              'bbp-parent-topic-'   . $topic_id,
2278              'bbp-reply-position-' . $reply_pos,
2279              $even_odd,
2280              $topic_author,
2281              $forum_moderator
2282          );
2283  
2284          // Run the topic classes through the post-class filters, which also
2285          // handles the escaping of each individual class.
2286          $post_classes = get_post_class( array_merge( $classes, $reply_classes ), $reply_id );
2287  
2288          // Filter
2289          $new_classes  = apply_filters( 'bbp_get_reply_class', $post_classes, $reply_id, $classes );
2290  
2291          // Return
2292          return 'class="' . implode( ' ', $new_classes ) . '"';
2293      }
2294  
2295  /** Pagination ****************************************************************/
2296  
2297  /**
2298   * Return the base URL used inside of pagination links
2299   *
2300   * @since 2.6.0 bbPress (r6679)
2301   *
2302   * @param int $topic_id
2303   * @return string
2304   */
2305  function bbp_get_replies_pagination_base( $topic_id = 0 ) {
2306  
2307      // If pretty permalinks are enabled, make our pagination pretty
2308      if ( bbp_use_pretty_urls() ) {
2309  
2310          // User's replies
2311          if ( bbp_is_single_user_replies() ) {
2312              $base = bbp_get_user_replies_created_url( bbp_get_displayed_user_id() );
2313  
2314          // Root profile page
2315          } elseif ( bbp_is_single_user() ) {
2316              $base = bbp_get_user_profile_url( bbp_get_displayed_user_id() );
2317  
2318          // Page or single post
2319          } elseif ( is_page() || is_single() ) {
2320              $base = get_permalink();
2321  
2322          // Single topic
2323          } else {
2324              $base = get_permalink( $topic_id );
2325          }
2326  
2327          $base = trailingslashit( $base ) . user_trailingslashit( bbp_get_paged_slug() . '/%#%/' );
2328  
2329      // Unpretty permalinks
2330      } else {
2331          $base = add_query_arg( 'paged', '%#%' );
2332      }
2333  
2334      // Filter & return
2335      return apply_filters( 'bbp_get_replies_pagination_base', $base, $topic_id );
2336  }
2337  
2338  /**
2339   * Output the topic pagination count
2340   *
2341   * The results are unescaped by design, to allow them to be filtered freely via
2342   * the 'bbp_get_topic_pagination_count' filter.
2343   *
2344   * @since 2.0.0 bbPress (r2519)
2345   *
2346   */
2347  function bbp_topic_pagination_count() {
2348      echo bbp_get_topic_pagination_count();
2349  }
2350      /**
2351       * Return the topic pagination count
2352       *
2353       * @since 2.0.0 bbPress (r2519)
2354       *
2355       * @return string Topic pagination count
2356       */
2357  	function bbp_get_topic_pagination_count() {
2358          $bbp = bbpress();
2359  
2360          // Define local variable(s)
2361          $retstr = '';
2362  
2363          // Set pagination values
2364          $count_int = intval( $bbp->reply_query->post_count     );
2365          $total_int = intval( $bbp->reply_query->found_posts    );
2366          $ppp_int   = intval( $bbp->reply_query->posts_per_page );
2367          $start_int = intval( ( $bbp->reply_query->paged - 1 ) * $ppp_int ) + 1;
2368          $to_int    = intval( ( $start_int + ( $ppp_int - 1 ) > $total_int )
2369              ? $total_int
2370              : $start_int + ( $ppp_int - 1 ) );
2371  
2372          // Format numbers for display
2373          $count_num = bbp_number_format( $count_int );
2374          $total_num = bbp_number_format( $total_int );
2375          $from_num  = bbp_number_format( $start_int );
2376          $to_num    = bbp_number_format( $to_int    );
2377  
2378          // We are threading replies
2379          if ( bbp_thread_replies() ) {
2380              $walker  = new BBP_Walker_Reply;
2381              $threads = absint( $walker->get_number_of_root_elements( $bbp->reply_query->posts ) - 1 );
2382              $retstr  = sprintf( _n( 'Viewing %1$s reply thread', 'Viewing %1$s reply threads', $threads, 'bbpress' ), bbp_number_format( $threads ) );
2383  
2384          // We are not including the lead topic
2385          } elseif ( bbp_show_lead_topic() ) {
2386  
2387              // Several replies in a topic with a single page
2388              if ( empty( $to_num ) ) {
2389                  $retstr = sprintf( _n( 'Viewing %1$s reply', 'Viewing %1$s replies', $total_int, 'bbpress' ), $total_num );
2390  
2391              // Several replies in a topic with several pages
2392              } else {
2393                  $retstr = sprintf( _n( 'Viewing %2$s replies (of %4$s total)', 'Viewing %1$s replies - %2$s through %3$s (of %4$s total)', $count_int, 'bbpress' ), $count_num, $from_num, $to_num, $total_num );
2394              }
2395  
2396          // We are including the lead topic
2397          } else {
2398  
2399              // Several posts in a topic with a single page
2400              if ( empty( $to_num ) ) {
2401                  $retstr = sprintf( _n( 'Viewing %1$s post', 'Viewing %1$s posts', $total_int, 'bbpress' ), $total_num );
2402  
2403              // Several posts in a topic with several pages
2404              } else {
2405                  $retstr = sprintf( _n( 'Viewing %2$s post (of %4$s total)', 'Viewing %1$s posts - %2$s through %3$s (of %4$s total)', $count_int, 'bbpress' ), $count_num, $from_num, $to_num, $total_num );
2406              }
2407          }
2408  
2409          // Escape results of _n()
2410          $retstr = esc_html( $retstr );
2411  
2412          // Filter & return
2413          return apply_filters( 'bbp_get_topic_pagination_count', $retstr );
2414      }
2415  
2416  /**
2417   * Output topic pagination links
2418   *
2419   * @since 2.0.0 bbPress (r2519)
2420   */
2421  function bbp_topic_pagination_links() {
2422      echo bbp_get_topic_pagination_links();
2423  }
2424      /**
2425       * Return topic pagination links
2426       *
2427       * @since 2.0.0 bbPress (r2519)
2428       *
2429       * @return string Topic pagination links
2430       */
2431  	function bbp_get_topic_pagination_links() {
2432          $bbp = bbpress();
2433  
2434          if ( ! isset( $bbp->reply_query->pagination_links ) || empty( $bbp->reply_query->pagination_links ) ) {
2435              return false;
2436          }
2437  
2438          // Filter & return
2439          return apply_filters( 'bbp_get_topic_pagination_links', $bbp->reply_query->pagination_links );
2440      }
2441  
2442  /** Forms *********************************************************************/
2443  
2444  /**
2445   * Output the value of reply content field
2446   *
2447   * @since 2.0.0 bbPress (r3130)
2448   */
2449  function bbp_form_reply_content() {
2450      echo bbp_get_form_reply_content();
2451  }
2452      /**
2453       * Return the value of reply content field
2454       *
2455       * @since 2.0.0 bbPress (r3130)
2456       *
2457       * @return string Value of reply content field
2458       */
2459  	function bbp_get_form_reply_content() {
2460  
2461          // Get _POST data
2462          if ( bbp_is_reply_form_post_request() && isset( $_POST['bbp_reply_content'] ) ) {
2463              $reply_content = wp_unslash( $_POST['bbp_reply_content'] );
2464  
2465          // Get edit data
2466          } elseif ( bbp_is_reply_edit() ) {
2467              $reply_content = bbp_get_global_post_field( 'post_content', 'raw' );
2468  
2469          // No data
2470          } else {
2471              $reply_content = '';
2472          }
2473  
2474          // Filter & return
2475          return apply_filters( 'bbp_get_form_reply_content', $reply_content );
2476      }
2477  
2478  /**
2479   * Output the value of the reply to field
2480   *
2481   * @since 2.4.0 bbPress (r4944)
2482   */
2483  function bbp_form_reply_to() {
2484      echo bbp_get_form_reply_to();
2485  }
2486  
2487      /**
2488       * Return the value of reply to field
2489       *
2490       * @since 2.4.0 bbPress (r4944)
2491       *
2492       * @return string Value of reply to field
2493       */
2494  	function bbp_get_form_reply_to() {
2495  
2496          // Set initial value
2497          $reply_to = 0;
2498  
2499          // Get $_REQUEST data
2500          if ( bbp_is_reply_form_post_request() && isset( $_REQUEST['bbp_reply_to'] ) ) {
2501              $reply_to = bbp_validate_reply_to( $_REQUEST['bbp_reply_to'] );
2502          }
2503  
2504          // If empty, get from meta
2505          if ( empty( $reply_to ) ) {
2506              $reply_to = bbp_get_reply_to();
2507          }
2508  
2509          // Filter & return
2510          return apply_filters( 'bbp_get_form_reply_to', $reply_to );
2511      }
2512  
2513  /**
2514   * Output a select box allowing to pick which reply an existing hierarchical
2515   * reply belongs to.
2516   *
2517   * @since 2.6.0 bbPress (r5387)
2518   *
2519   * @param int $reply_id
2520   */
2521  function bbp_reply_to_dropdown( $reply_id = 0 ) {
2522      echo bbp_get_reply_to_dropdown( $reply_id );
2523  }
2524      /**
2525       * Return a select box allowing to pick which topic/reply a reply belongs.
2526       *
2527       * @since 2.6.0 bbPress (r5387)
2528       *
2529       * @param int $reply_id
2530       *
2531       * @return string The dropdown
2532       */
2533  	function bbp_get_reply_to_dropdown( $reply_id = 0 ) {
2534  
2535          // Validate the reply data
2536          $reply_id = bbp_get_reply_id( $reply_id );
2537          $reply_to = bbp_get_reply_to( $reply_id );
2538          $topic_id = bbp_get_reply_topic_id( $reply_id );
2539  
2540          // Get the replies
2541          $posts = get_posts( array(
2542              'post_type'   => bbp_get_reply_post_type(),
2543              'post_status' => bbp_get_public_status_id(),
2544              'post_parent' => $topic_id,
2545              'numberposts' => -1,
2546              'orderby'     => 'menu_order',
2547              'order'       => 'ASC',
2548          ) );
2549  
2550          // Append `reply_to` for each reply so it can be walked
2551          foreach ( $posts as &$post ) {
2552  
2553              // Check for reply post type
2554              $_reply_to = bbp_get_reply_to( $post->ID );
2555  
2556              // Make sure it's a reply to a reply
2557              if ( empty( $_reply_to ) || ( $topic_id === $_reply_to ) ) {
2558                  $_reply_to = 0;
2559              }
2560  
2561              // Add reply_to to the post object so we can walk it later
2562              $post->reply_to = $_reply_to;
2563          }
2564  
2565          // Default "None" text
2566          $show_none = ( 0 === $reply_id )
2567              ? esc_attr_x( 'None', 'Default reply to dropdown text', 'bbpress' )
2568              : sprintf( esc_attr__( '%1$s - %2$s', 'bbpress' ), $topic_id, bbp_get_topic_title( $topic_id ) );
2569  
2570          // Get the dropdown and return it
2571          $retval = bbp_get_dropdown( array(
2572              'show_none'    => $show_none,
2573              'select_id'    => 'bbp_reply_to',
2574              'select_class' => 'bbp_dropdown',
2575              'exclude'      => $reply_id,
2576              'selected'     => $reply_to,
2577              'post_parent'  => $topic_id,
2578              'post_type'    => bbp_get_reply_post_type(),
2579              'max_depth'    => bbp_thread_replies_depth(),
2580              'page'         => 1,
2581              'per_page'     => -1,
2582              'walker'       => new BBP_Walker_Reply_Dropdown(),
2583              'posts'        => $posts
2584          ) );
2585  
2586          // Filter & return
2587          return apply_filters( 'bbp_get_reply_to_dropdown', $retval, $reply_id, $reply_to, $topic_id );
2588      }
2589  
2590  /**
2591   * Output checked value of reply log edit field
2592   *
2593   * @since 2.0.0 bbPress (r3130)
2594   */
2595  function bbp_form_reply_log_edit() {
2596      echo bbp_get_form_reply_log_edit();
2597  }
2598      /**
2599       * Return checked value of reply log edit field
2600       *
2601       * @since 2.0.0 bbPress (r3130)
2602       *
2603       * @return string Reply log edit checked value
2604       */
2605  	function bbp_get_form_reply_log_edit() {
2606  
2607          // Get _POST data
2608          if ( bbp_is_reply_form_post_request() && isset( $_POST['bbp_log_reply_edit'] ) ) {
2609              $reply_revision = (bool) $_POST['bbp_log_reply_edit'];
2610  
2611          // No data
2612          } else {
2613              $reply_revision = true;
2614          }
2615  
2616          // Get checked output
2617          $checked = checked( $reply_revision, true, false );
2618  
2619          // Filter & return
2620          return apply_filters( 'bbp_get_form_reply_log_edit', $checked, $reply_revision );
2621      }
2622  
2623  /**
2624   * Output the value of the reply edit reason
2625   *
2626   * @since 2.0.0 bbPress (r3130)
2627   */
2628  function bbp_form_reply_edit_reason() {
2629      echo bbp_get_form_reply_edit_reason();
2630  }
2631      /**
2632       * Return the value of the reply edit reason
2633       *
2634       * @since 2.0.0 bbPress (r3130)
2635       *
2636       * @return string Reply edit reason value
2637       */
2638  	function bbp_get_form_reply_edit_reason() {
2639  
2640          // Get _POST data
2641          if ( bbp_is_reply_form_post_request() && isset( $_POST['bbp_reply_edit_reason'] ) ) {
2642              $reply_edit_reason = wp_unslash( $_POST['bbp_reply_edit_reason'] );
2643  
2644          // No data
2645          } else {
2646              $reply_edit_reason = '';
2647          }
2648  
2649          // Filter & return
2650          return apply_filters( 'bbp_get_form_reply_edit_reason', $reply_edit_reason );
2651      }
2652  
2653  /**
2654   * Output value reply status dropdown
2655   *
2656   * @since 2.6.0 bbPress (r5399)
2657   *
2658   * @param $args This function supports these arguments:
2659   *  - select_id: Select id. Defaults to bbp_reply_status
2660   *  - tab: Deprecated. Tabindex
2661   *  - reply_id: Reply id
2662   *  - selected: Override the selected option
2663   */
2664  function bbp_form_reply_status_dropdown( $args = array() ) {
2665      echo bbp_get_form_reply_status_dropdown( $args );
2666  }
2667      /**
2668       * Returns reply status dropdown
2669       *
2670       * This dropdown is only intended to be seen by users with the 'moderate'
2671       * capability. Because of this, no additional capability checks are performed
2672       * within this function to check available reply statuses.
2673       *
2674       * @since 2.6.0 bbPress (r5399)
2675       *
2676       * @param $args This function supports these arguments:
2677       *  - select_id: Select id. Defaults to bbp_reply_status
2678       *  - tab: Deprecated. Tabindex
2679       *  - reply_id: Reply id
2680       *  - selected: Override the selected option
2681       */
2682  	function bbp_get_form_reply_status_dropdown( $args = array() ) {
2683  
2684          // Parse arguments against default values
2685          $r = bbp_parse_args( $args, array(
2686              'select_id'    => 'bbp_reply_status',
2687              'select_class' => 'bbp_dropdown',
2688              'tab'          => false,
2689              'reply_id'     => 0,
2690              'selected'     => false
2691          ), 'reply_status_dropdown' );
2692  
2693          // No specific selected value passed
2694          if ( empty( $r['selected'] ) ) {
2695  
2696              // Post value is passed
2697              if ( bbp_is_reply_form_post_request() && isset( $_POST[ $r['select_id'] ] ) ) {
2698                  $r['selected'] = sanitize_key( $_POST[ $r['select_id'] ] );
2699  
2700              // No Post value was passed
2701              } else {
2702  
2703                  // Edit reply
2704                  if ( bbp_is_reply_edit() ) {
2705                      $r['reply_id'] = bbp_get_reply_id( $r['reply_id'] );
2706                      $r['selected'] = bbp_get_reply_status( $r['reply_id'] );
2707  
2708                  // New reply
2709                  } else {
2710                      $r['selected'] = bbp_get_public_status_id();
2711                  }
2712              }
2713          }
2714  
2715          // Start an output buffer, we'll finish it after the select loop
2716          ob_start(); ?>
2717  
2718          <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'] ); ?>>
2719  
2720              <?php foreach ( bbp_get_reply_statuses( $r['reply_id'] ) as $key => $label ) : ?>
2721  
2722                  <option value="<?php echo esc_attr( $key ); ?>"<?php selected( $key, $r['selected'] ); ?>><?php echo esc_html( $label ); ?></option>
2723  
2724              <?php endforeach; ?>
2725  
2726          </select>
2727  
2728          <?php
2729  
2730          // Filter & return
2731          return apply_filters( 'bbp_get_form_reply_status_dropdown', ob_get_clean(), $r, $args );
2732      }
2733  
2734  /**
2735   * Verify if a POST request came from a failed reply attempt.
2736   *
2737   * Used to avoid cross-site request forgeries when checking posted reply form
2738   * content.
2739   *
2740   * @see bbp_reply_form_fields()
2741   *
2742   * @since 2.6.0 bbPress (r5558)
2743   *
2744   * @return boolean True if is a post request with valid nonce
2745   */
2746  function bbp_is_reply_form_post_request() {
2747  
2748      // Bail if not a post request
2749      if ( ! bbp_is_post_request() ) {
2750          return false;
2751      }
2752  
2753      // Creating a new reply
2754      if ( bbp_verify_nonce_request( 'bbp-new-reply' ) ) {
2755          return true;
2756      }
2757  
2758      // Editing an existing reply
2759      if ( bbp_verify_nonce_request( 'bbp-edit-reply' ) ) {
2760          return true;
2761      }
2762  
2763      return false;
2764  }


Generated: Tue Jul 16 01:01:32 2019 Cross-referenced by PHPXref 0.7.1