: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if ( isset( $comment_args['include_unapproved'] ) ) {
$top_level_args['include_unapproved'] = $comment_args['include_unapproved'];
* Filters the arguments used in the top level comments query.
* @see WP_Comment_Query::__construct()
* @param array $top_level_args {
* The top level query arguments for the comments template.
* @type bool $count Whether to return a comment count.
* @type string|array $orderby The field(s) to order by.
* @type int $post_id The post ID.
* @type string|array $status The comment status to limit results by.
$top_level_args = apply_filters( 'comments_template_top_level_query_args', $top_level_args );
$top_level_count = $top_level_query->query( $top_level_args );
$comment_args['offset'] = ( (int) ceil( $top_level_count / $per_page ) - 1 ) * $per_page;
* Filters the arguments used to query comments in comments_template().
* @see WP_Comment_Query::__construct()
* @param array $comment_args {
* Array of WP_Comment_Query arguments.
* @type string|array $orderby Field(s) to order by.
* @type string $order Order of results. Accepts 'ASC' or 'DESC'.
* @type string $status Comment status.
* @type array $include_unapproved Array of IDs or email addresses whose unapproved comments
* will be included in results.
* @type int $post_id ID of the post.
* @type bool $no_found_rows Whether to refrain from querying for found rows.
* @type bool $update_comment_meta_cache Whether to prime cache for comment meta.
* @type bool|string $hierarchical Whether to query for comments hierarchically.
* @type int $offset Comment offset.
* @type int $number Number of comments to fetch.
$comment_args = apply_filters( 'comments_template_query_args', $comment_args );
$comment_query = new WP_Comment_Query( $comment_args );
$_comments = $comment_query->comments;
// Trees must be flattened before they're passed to the walker.
if ( $comment_args['hierarchical'] ) {
$comments_flat = array();
foreach ( $_comments as $_comment ) {
$comments_flat[] = $_comment;
$comment_children = $_comment->get_children(
'status' => $comment_args['status'],
'orderby' => $comment_args['orderby'],
foreach ( $comment_children as $comment_child ) {
$comments_flat[] = $comment_child;
$comments_flat = $_comments;
* Filters the comments array.
* @param array $comments Array of comments supplied to the comments template.
* @param int $post_id Post ID.
$wp_query->comments = apply_filters( 'comments_array', $comments_flat, $post->ID );
$comments = &$wp_query->comments;
$wp_query->comment_count = count( $wp_query->comments );
$wp_query->max_num_comment_pages = $comment_query->max_num_pages;
if ( $separate_comments ) {
$wp_query->comments_by_type = separate_comments( $comments );
$comments_by_type = &$wp_query->comments_by_type;
$wp_query->comments_by_type = array();
$overridden_cpage = false;
if ( '' == get_query_var( 'cpage' ) && $wp_query->max_num_comment_pages > 1 ) {
set_query_var( 'cpage', 'newest' === get_option( 'default_comments_page' ) ? get_comment_pages_count() : 1 );
$overridden_cpage = true;
if ( ! defined( 'COMMENTS_TEMPLATE' ) ) {
define( 'COMMENTS_TEMPLATE', true );
$theme_template = trailingslashit( $wp_stylesheet_path ) . $file;
* Filters the path to the theme template file used for the comments template.
* @param string $theme_template The path to the theme template file.
$include = apply_filters( 'comments_template', $theme_template );
if ( file_exists( $include ) ) {
} elseif ( file_exists( trailingslashit( $wp_template_path ) . $file ) ) {
require trailingslashit( $wp_template_path ) . $file;
} else { // Backward compat code will be removed in a future release.
require ABSPATH . WPINC . '/theme-compat/comments.php';
* Displays the link to the comments for the current post ID.
* @param false|string $zero Optional. String to display when no comments. Default false.
* @param false|string $one Optional. String to display when only one comment is available. Default false.
* @param false|string $more Optional. String to display when there are more than one comment. Default false.
* @param string $css_class Optional. CSS class to use for comments. Default empty.
* @param false|string $none Optional. String to display when comments have been turned off. Default false.
function comments_popup_link( $zero = false, $one = false, $more = false, $css_class = '', $none = false ) {
$post_title = get_the_title();
$comments_number = get_comments_number( $post_id );
/* translators: %s: Post title. */
$zero = sprintf( __( 'No Comments<span class="screen-reader-text"> on %s</span>' ), $post_title );
/* translators: %s: Post title. */
$one = sprintf( __( '1 Comment<span class="screen-reader-text"> on %s</span>' ), $post_title );
/* translators: 1: Number of comments, 2: Post title. */
'%1$s Comment<span class="screen-reader-text"> on %2$s</span>',
'%1$s Comments<span class="screen-reader-text"> on %2$s</span>',
$more = sprintf( $more, number_format_i18n( $comments_number ), $post_title );
/* translators: %s: Post title. */
$none = sprintf( __( 'Comments Off<span class="screen-reader-text"> on %s</span>' ), $post_title );
if ( 0 == $comments_number && ! comments_open() && ! pings_open() ) {
! empty( $css_class ) ? ' class="' . esc_attr( $css_class ) . '"' : '',
if ( post_password_required() ) {
_e( 'Enter your password to view comments.' );
if ( 0 == $comments_number ) {
$respond_link = get_permalink() . '#respond';
* Filters the respond link when a post has no comments.
* @param string $respond_link The default response link.
* @param int $post_id The post ID.
$comments_link = apply_filters( 'respond_link', $respond_link, $post_id );
$comments_link = get_comments_link();
* Filters the comments link attributes for display.
* @param string $link_attributes The comments link attributes. Default empty.
$link_attributes = apply_filters( 'comments_popup_link_attributes', $link_attributes );
'<a href="%1$s"%2$s%3$s>%4$s</a>',
esc_url( $comments_link ),
! empty( $css_class ) ? ' class="' . $css_class . '" ' : '',
get_comments_number_text( $zero, $one, $more )
* Retrieves HTML content for reply to comment link.
* @since 4.4.0 Added the ability for `$comment` to also accept a WP_Comment object.
* Optional. Override default arguments.
* @type string $add_below The first part of the selector used to identify the comment to respond below.
* The resulting value is passed as the first parameter to addComment.moveForm(),
* concatenated as $add_below-$comment->comment_ID. Default 'comment'.
* @type string $respond_id The selector identifying the responding comment. Passed as the third parameter
* to addComment.moveForm(), and appended to the link URL as a hash value.
* @type string $reply_text The text of the Reply link. Default 'Reply'.
* @type string $login_text The text of the link to reply if logged out. Default 'Log in to Reply'.
* @type int $max_depth The max depth of the comment tree. Default 0.
* @type int $depth The depth of the new comment. Must be greater than 0 and less than the value
* of the 'thread_comments_depth' option set in Settings > Discussion. Default 0.
* @type string $before The text or HTML to add before the reply link. Default empty.
* @type string $after The text or HTML to add after the reply link. Default empty.
* @param int|WP_Comment $comment Optional. Comment being replied to. Default current comment.
* @param int|WP_Post $post Optional. Post ID or WP_Post object the comment is going to be displayed on.
* @return string|false|null Link to show comment form, if successful. False, if comments are closed.
function get_comment_reply_link( $args = array(), $comment = null, $post = null ) {
'add_below' => 'comment',
'respond_id' => 'respond',
'reply_text' => __( 'Reply' ),
/* translators: Comment reply button text. %s: Comment author name. */
'reply_to_text' => __( 'Reply to %s' ),
'login_text' => __( 'Log in to Reply' ),
$args = wp_parse_args( $args, $defaults );
if ( 0 == $args['depth'] || $args['max_depth'] <= $args['depth'] ) {
$comment = get_comment( $comment );
if ( empty( $comment ) ) {
$post = $comment->comment_post_ID;
$post = get_post( $post );
if ( ! comments_open( $post->ID ) ) {
if ( get_option( 'page_comments' ) ) {
$permalink = str_replace( '#comment-' . $comment->comment_ID, '', get_comment_link( $comment ) );
$permalink = get_permalink( $post->ID );
* Filters the comment reply link arguments.
* @param array $args Comment reply link arguments. See get_comment_reply_link()
* for more information on accepted arguments.
* @param WP_Comment $comment The object of the comment being replied to.
* @param WP_Post $post The WP_Post object.
$args = apply_filters( 'comment_reply_link_args', $args, $comment, $post );
if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
'<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
esc_url( wp_login_url( get_permalink() ) ),
$data_attributes = array(
'commentid' => $comment->comment_ID,
'belowelement' => $args['add_below'] . '-' . $comment->comment_ID,
'respondelement' => $args['respond_id'],
'replyto' => sprintf( $args['reply_to_text'], get_comment_author( $comment ) ),
$data_attribute_string = '';
foreach ( $data_attributes as $name => $value ) {
$data_attribute_string .= " data-{$name}=\"" . esc_attr( $value ) . '"';
$data_attribute_string = trim( $data_attribute_string );
"<a rel='nofollow' class='comment-reply-link' href='%s' %s aria-label='%s'>%s</a>",
'replytocom' => $comment->comment_ID,
'moderation-hash' => false,
) . '#' . $args['respond_id'],
esc_attr( sprintf( $args['reply_to_text'], get_comment_author( $comment ) ) ),
$comment_reply_link = $args['before'] . $link . $args['after'];
* Filters the comment reply link.
* @param string $comment_reply_link The HTML markup for the comment reply link.
* @param array $args An array of arguments overriding the defaults.
* @param WP_Comment $comment The object of the comment being replied.
* @param WP_Post $post The WP_Post object.
return apply_filters( 'comment_reply_link', $comment_reply_link, $args, $comment, $post );
* Displays the HTML content for reply to comment link.
* @see get_comment_reply_link()
* @param array $args Optional. Override default options. Default empty array.
* @param int|WP_Comment $comment Optional. Comment being replied to. Default current comment.
* @param int|WP_Post $post Optional. Post ID or WP_Post object the comment is going to be displayed on.
function comment_reply_link( $args = array(), $comment = null, $post = null ) {
echo get_comment_reply_link( $args, $comment, $post );
* Retrieves HTML content for reply to post link.
* Optional. Override default arguments.
* @type string $add_below The first part of the selector used to identify the comment to respond below.
* The resulting value is passed as the first parameter to addComment.moveForm(),
* concatenated as $add_below-$comment->comment_ID. Default is 'post'.
* @type string $respond_id The selector identifying the responding comment. Passed as the third parameter
* to addComment.moveForm(), and appended to the link URL as a hash value.
* @type string $reply_text Text of the Reply link. Default is 'Leave a Comment'.
* @type string $login_text Text of the link to reply if logged out. Default is 'Log in to leave a Comment'.
* @type string $before Text or HTML to add before the reply link. Default empty.
* @type string $after Text or HTML to add after the reply link. Default empty.
* @param int|WP_Post $post Optional. Post ID or WP_Post object the comment is going to be displayed on.
* @return string|false|null Link to show comment form, if successful. False, if comments are closed.
function get_post_reply_link( $args = array(), $post = null ) {
'respond_id' => 'respond',
'reply_text' => __( 'Leave a Comment' ),
'login_text' => __( 'Log in to leave a Comment' ),
$args = wp_parse_args( $args, $defaults );
$post = get_post( $post );
if ( ! comments_open( $post->ID ) ) {
if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
'<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
wp_login_url( get_permalink() ),
'return addComment.moveForm( "%1$s-%2$s", "0", "%3$s", "%2$s" )',
"<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s'>%s</a>",
get_permalink( $post->ID ) . '#' . $args['respond_id'],
$post_reply_link = $args['before'] . $link . $args['after'];
* Filters the formatted post comments link HTML.
* @param string $post_reply_link The HTML-formatted post comments link.
* @param int|WP_Post $post The post ID or WP_Post object.
return apply_filters( 'post_comments_link', $post_reply_link, $post );
* Displays the HTML content for reply to post link.
* @see get_post_reply_link()
* @param array $args Optional. Override default options. Default empty array.
* @param int|WP_Post $post Optional. Post ID or WP_Post object the comment is going to be displayed on.
function post_reply_link( $args = array(), $post = null ) {
echo get_post_reply_link( $args, $post );
* Retrieves HTML content for cancel comment reply link.
* @since 6.2.0 Added the `$post` parameter.
* @param string $link_text Optional. Text to display for cancel reply link. If empty,
* defaults to 'Click here to cancel reply'. Default empty.
* @param int|WP_Post|null $post Optional. The post the comment thread is being
* displayed for. Defaults to the current global post.
function get_cancel_comment_reply_link( $link_text = '', $post = null ) {
if ( empty( $link_text ) ) {
$link_text = __( 'Click here to cancel reply.' );
$post = get_post( $post );
$reply_to_id = $post ? _get_comment_reply_id( $post->ID ) : 0;
$link_style = 0 !== $reply_to_id ? '' : ' style="display:none;"';
$link_url = esc_url( remove_query_arg( array( 'replytocom', 'unapproved', 'moderation-hash' ) ) ) . '#respond';
$cancel_comment_reply_link = sprintf(
'<a rel="nofollow" id="cancel-comment-reply-link" href="%1$s"%2$s>%3$s</a>',
* Filters the cancel comment reply link HTML.
* @param string $cancel_comment_reply_link The HTML-formatted cancel comment reply link.