angelovcom.net

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

comment-template.php (94954B)


      1 <?php
      2 /**
      3  * Comment template functions
      4  *
      5  * These functions are meant to live inside of the WordPress loop.
      6  *
      7  * @package WordPress
      8  * @subpackage Template
      9  */
     10 
     11 /**
     12  * Retrieves the author of the current comment.
     13  *
     14  * If the comment has an empty comment_author field, then 'Anonymous' person is
     15  * assumed.
     16  *
     17  * @since 1.5.0
     18  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
     19  *
     20  * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to retrieve the author.
     21  *                                   Default current comment.
     22  * @return string The comment author
     23  */
     24 function get_comment_author( $comment_ID = 0 ) {
     25 	$comment = get_comment( $comment_ID );
     26 
     27 	if ( empty( $comment->comment_author ) ) {
     28 		$user = $comment->user_id ? get_userdata( $comment->user_id ) : false;
     29 		if ( $user ) {
     30 			$author = $user->display_name;
     31 		} else {
     32 			$author = __( 'Anonymous' );
     33 		}
     34 	} else {
     35 		$author = $comment->comment_author;
     36 	}
     37 
     38 	/**
     39 	 * Filters the returned comment author name.
     40 	 *
     41 	 * @since 1.5.0
     42 	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
     43 	 *
     44 	 * @param string     $author     The comment author's username.
     45 	 * @param int        $comment_ID The comment ID.
     46 	 * @param WP_Comment $comment    The comment object.
     47 	 */
     48 	return apply_filters( 'get_comment_author', $author, $comment->comment_ID, $comment );
     49 }
     50 
     51 /**
     52  * Displays the author of the current comment.
     53  *
     54  * @since 0.71
     55  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
     56  *
     57  * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to print the author.
     58  *                                   Default current comment.
     59  */
     60 function comment_author( $comment_ID = 0 ) {
     61 	$comment = get_comment( $comment_ID );
     62 	$author  = get_comment_author( $comment );
     63 
     64 	/**
     65 	 * Filters the comment author's name for display.
     66 	 *
     67 	 * @since 1.2.0
     68 	 * @since 4.1.0 The `$comment_ID` parameter was added.
     69 	 *
     70 	 * @param string $author     The comment author's username.
     71 	 * @param int    $comment_ID The comment ID.
     72 	 */
     73 	echo apply_filters( 'comment_author', $author, $comment->comment_ID );
     74 }
     75 
     76 /**
     77  * Retrieves the email of the author of the current comment.
     78  *
     79  * @since 1.5.0
     80  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
     81  *
     82  * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to get the author's email.
     83  *                                   Default current comment.
     84  * @return string The current comment author's email
     85  */
     86 function get_comment_author_email( $comment_ID = 0 ) {
     87 	$comment = get_comment( $comment_ID );
     88 
     89 	/**
     90 	 * Filters the comment author's returned email address.
     91 	 *
     92 	 * @since 1.5.0
     93 	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
     94 	 *
     95 	 * @param string     $comment_author_email The comment author's email address.
     96 	 * @param int        $comment_ID           The comment ID.
     97 	 * @param WP_Comment $comment              The comment object.
     98 	 */
     99 	return apply_filters( 'get_comment_author_email', $comment->comment_author_email, $comment->comment_ID, $comment );
    100 }
    101 
    102 /**
    103  * Displays the email of the author of the current global $comment.
    104  *
    105  * Care should be taken to protect the email address and assure that email
    106  * harvesters do not capture your commenter's email address. Most assume that
    107  * their email address will not appear in raw form on the site. Doing so will
    108  * enable anyone, including those that people don't want to get the email
    109  * address and use it for their own means good and bad.
    110  *
    111  * @since 0.71
    112  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    113  *
    114  * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to print the author's email.
    115  *                                   Default current comment.
    116  */
    117 function comment_author_email( $comment_ID = 0 ) {
    118 	$comment      = get_comment( $comment_ID );
    119 	$author_email = get_comment_author_email( $comment );
    120 
    121 	/**
    122 	 * Filters the comment author's email for display.
    123 	 *
    124 	 * @since 1.2.0
    125 	 * @since 4.1.0 The `$comment_ID` parameter was added.
    126 	 *
    127 	 * @param string $author_email The comment author's email address.
    128 	 * @param int    $comment_ID   The comment ID.
    129 	 */
    130 	echo apply_filters( 'author_email', $author_email, $comment->comment_ID );
    131 }
    132 
    133 /**
    134  * Displays the HTML email link to the author of the current comment.
    135  *
    136  * Care should be taken to protect the email address and assure that email
    137  * harvesters do not capture your commenter's email address. Most assume that
    138  * their email address will not appear in raw form on the site. Doing so will
    139  * enable anyone, including those that people don't want to get the email
    140  * address and use it for their own means good and bad.
    141  *
    142  * @since 0.71
    143  * @since 4.6.0 Added the `$comment` parameter.
    144  *
    145  * @param string         $linktext Optional. Text to display instead of the comment author's email address.
    146  *                                 Default empty.
    147  * @param string         $before   Optional. Text or HTML to display before the email link. Default empty.
    148  * @param string         $after    Optional. Text or HTML to display after the email link. Default empty.
    149  * @param int|WP_Comment $comment  Optional. Comment ID or WP_Comment object. Default is the current comment.
    150  */
    151 function comment_author_email_link( $linktext = '', $before = '', $after = '', $comment = null ) {
    152 	$link = get_comment_author_email_link( $linktext, $before, $after, $comment );
    153 	if ( $link ) {
    154 		echo $link;
    155 	}
    156 }
    157 
    158 /**
    159  * Returns the HTML email link to the author of the current comment.
    160  *
    161  * Care should be taken to protect the email address and assure that email
    162  * harvesters do not capture your commenter's email address. Most assume that
    163  * their email address will not appear in raw form on the site. Doing so will
    164  * enable anyone, including those that people don't want to get the email
    165  * address and use it for their own means good and bad.
    166  *
    167  * @since 2.7.0
    168  * @since 4.6.0 Added the `$comment` parameter.
    169  *
    170  * @param string         $linktext Optional. Text to display instead of the comment author's email address.
    171  *                                 Default empty.
    172  * @param string         $before   Optional. Text or HTML to display before the email link. Default empty.
    173  * @param string         $after    Optional. Text or HTML to display after the email link. Default empty.
    174  * @param int|WP_Comment $comment  Optional. Comment ID or WP_Comment object. Default is the current comment.
    175  * @return string HTML markup for the comment author email link. By default, the email address is obfuscated
    176  *                via the {@see 'comment_email'} filter with antispambot().
    177  */
    178 function get_comment_author_email_link( $linktext = '', $before = '', $after = '', $comment = null ) {
    179 	$comment = get_comment( $comment );
    180 
    181 	/**
    182 	 * Filters the comment author's email for display.
    183 	 *
    184 	 * Care should be taken to protect the email address and assure that email
    185 	 * harvesters do not capture your commenter's email address.
    186 	 *
    187 	 * @since 1.2.0
    188 	 * @since 4.1.0 The `$comment` parameter was added.
    189 	 *
    190 	 * @param string     $comment_author_email The comment author's email address.
    191 	 * @param WP_Comment $comment              The comment object.
    192 	 */
    193 	$email = apply_filters( 'comment_email', $comment->comment_author_email, $comment );
    194 
    195 	if ( ( ! empty( $email ) ) && ( '@' !== $email ) ) {
    196 		$display = ( '' !== $linktext ) ? $linktext : $email;
    197 		$return  = $before;
    198 		$return .= sprintf( '<a href="%1$s">%2$s</a>', esc_url( 'mailto:' . $email ), esc_html( $display ) );
    199 		$return .= $after;
    200 		return $return;
    201 	} else {
    202 		return '';
    203 	}
    204 }
    205 
    206 /**
    207  * Retrieves the HTML link to the URL of the author of the current comment.
    208  *
    209  * Both get_comment_author_url() and get_comment_author() rely on get_comment(),
    210  * which falls back to the global comment variable if the $comment_ID argument is empty.
    211  *
    212  * @since 1.5.0
    213  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    214  *
    215  * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to get the author's link.
    216  *                                   Default current comment.
    217  * @return string The comment author name or HTML link for author's URL.
    218  */
    219 function get_comment_author_link( $comment_ID = 0 ) {
    220 	$comment = get_comment( $comment_ID );
    221 	$url     = get_comment_author_url( $comment );
    222 	$author  = get_comment_author( $comment );
    223 
    224 	if ( empty( $url ) || 'http://' === $url ) {
    225 		$return = $author;
    226 	} else {
    227 		$return = "<a href='$url' rel='external nofollow ugc' class='url'>$author</a>";
    228 	}
    229 
    230 	/**
    231 	 * Filters the comment author's link for display.
    232 	 *
    233 	 * @since 1.5.0
    234 	 * @since 4.1.0 The `$author` and `$comment_ID` parameters were added.
    235 	 *
    236 	 * @param string $return     The HTML-formatted comment author link.
    237 	 *                           Empty for an invalid URL.
    238 	 * @param string $author     The comment author's username.
    239 	 * @param int    $comment_ID The comment ID.
    240 	 */
    241 	return apply_filters( 'get_comment_author_link', $return, $author, $comment->comment_ID );
    242 }
    243 
    244 /**
    245  * Displays the HTML link to the URL of the author of the current comment.
    246  *
    247  * @since 0.71
    248  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    249  *
    250  * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to print the author's link.
    251  *                                   Default current comment.
    252  */
    253 function comment_author_link( $comment_ID = 0 ) {
    254 	echo get_comment_author_link( $comment_ID );
    255 }
    256 
    257 /**
    258  * Retrieve the IP address of the author of the current comment.
    259  *
    260  * @since 1.5.0
    261  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    262  *
    263  * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to get the author's IP address.
    264  *                                   Default current comment.
    265  * @return string Comment author's IP address.
    266  */
    267 function get_comment_author_IP( $comment_ID = 0 ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
    268 	$comment = get_comment( $comment_ID );
    269 
    270 	/**
    271 	 * Filters the comment author's returned IP address.
    272 	 *
    273 	 * @since 1.5.0
    274 	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
    275 	 *
    276 	 * @param string     $comment_author_IP The comment author's IP address.
    277 	 * @param int        $comment_ID        The comment ID.
    278 	 * @param WP_Comment $comment           The comment object.
    279 	 */
    280 	return apply_filters( 'get_comment_author_IP', $comment->comment_author_IP, $comment->comment_ID, $comment );  // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
    281 }
    282 
    283 /**
    284  * Displays the IP address of the author of the current comment.
    285  *
    286  * @since 0.71
    287  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    288  *
    289  * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to print the author's IP address.
    290  *                                   Default current comment.
    291  */
    292 function comment_author_IP( $comment_ID = 0 ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
    293 	echo esc_html( get_comment_author_IP( $comment_ID ) );
    294 }
    295 
    296 /**
    297  * Retrieves the URL of the author of the current comment, not linked.
    298  *
    299  * @since 1.5.0
    300  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    301  *
    302  * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to get the author's URL.
    303  *                                   Default current comment.
    304  * @return string Comment author URL, if provided, an empty string otherwise.
    305  */
    306 function get_comment_author_url( $comment_ID = 0 ) {
    307 	$comment = get_comment( $comment_ID );
    308 	$url     = '';
    309 	$id      = 0;
    310 
    311 	if ( ! empty( $comment ) ) {
    312 		$author_url = ( 'http://' === $comment->comment_author_url ) ? '' : $comment->comment_author_url;
    313 		$url        = esc_url( $author_url, array( 'http', 'https' ) );
    314 		$id         = $comment->comment_ID;
    315 	}
    316 
    317 	/**
    318 	 * Filters the comment author's URL.
    319 	 *
    320 	 * @since 1.5.0
    321 	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
    322 	 *
    323 	 * @param string     $url        The comment author's URL.
    324 	 * @param int        $comment_ID The comment ID.
    325 	 * @param WP_Comment $comment    The comment object.
    326 	 */
    327 	return apply_filters( 'get_comment_author_url', $url, $id, $comment );
    328 }
    329 
    330 /**
    331  * Displays the URL of the author of the current comment, not linked.
    332  *
    333  * @since 0.71
    334  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    335  *
    336  * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to print the author's URL.
    337  *                                   Default current comment.
    338  */
    339 function comment_author_url( $comment_ID = 0 ) {
    340 	$comment    = get_comment( $comment_ID );
    341 	$author_url = get_comment_author_url( $comment );
    342 
    343 	/**
    344 	 * Filters the comment author's URL for display.
    345 	 *
    346 	 * @since 1.2.0
    347 	 * @since 4.1.0 The `$comment_ID` parameter was added.
    348 	 *
    349 	 * @param string $author_url The comment author's URL.
    350 	 * @param int    $comment_ID The comment ID.
    351 	 */
    352 	echo apply_filters( 'comment_url', $author_url, $comment->comment_ID );
    353 }
    354 
    355 /**
    356  * Retrieves the HTML link of the URL of the author of the current comment.
    357  *
    358  * $linktext parameter is only used if the URL does not exist for the comment
    359  * author. If the URL does exist then the URL will be used and the $linktext
    360  * will be ignored.
    361  *
    362  * Encapsulate the HTML link between the $before and $after. So it will appear
    363  * in the order of $before, link, and finally $after.
    364  *
    365  * @since 1.5.0
    366  * @since 4.6.0 Added the `$comment` parameter.
    367  *
    368  * @param string         $linktext Optional. The text to display instead of the comment
    369  *                                 author's email address. Default empty.
    370  * @param string         $before   Optional. The text or HTML to display before the email link.
    371  *                                 Default empty.
    372  * @param string         $after    Optional. The text or HTML to display after the email link.
    373  *                                 Default empty.
    374  * @param int|WP_Comment $comment  Optional. Comment ID or WP_Comment object.
    375  *                                 Default is the current comment.
    376  * @return string The HTML link between the $before and $after parameters.
    377  */
    378 function get_comment_author_url_link( $linktext = '', $before = '', $after = '', $comment = 0 ) {
    379 	$url     = get_comment_author_url( $comment );
    380 	$display = ( '' !== $linktext ) ? $linktext : $url;
    381 	$display = str_replace( 'http://www.', '', $display );
    382 	$display = str_replace( 'http://', '', $display );
    383 
    384 	if ( '/' === substr( $display, -1 ) ) {
    385 		$display = substr( $display, 0, -1 );
    386 	}
    387 
    388 	$return = "$before<a href='$url' rel='external'>$display</a>$after";
    389 
    390 	/**
    391 	 * Filters the comment author's returned URL link.
    392 	 *
    393 	 * @since 1.5.0
    394 	 *
    395 	 * @param string $return The HTML-formatted comment author URL link.
    396 	 */
    397 	return apply_filters( 'get_comment_author_url_link', $return );
    398 }
    399 
    400 /**
    401  * Displays the HTML link of the URL of the author of the current comment.
    402  *
    403  * @since 0.71
    404  * @since 4.6.0 Added the `$comment` parameter.
    405  *
    406  * @param string         $linktext Optional. Text to display instead of the comment author's
    407  *                                 email address. Default empty.
    408  * @param string         $before   Optional. Text or HTML to display before the email link.
    409  *                                 Default empty.
    410  * @param string         $after    Optional. Text or HTML to display after the email link.
    411  *                                 Default empty.
    412  * @param int|WP_Comment $comment  Optional. Comment ID or WP_Comment object.
    413  *                                 Default is the current comment.
    414  */
    415 function comment_author_url_link( $linktext = '', $before = '', $after = '', $comment = 0 ) {
    416 	echo get_comment_author_url_link( $linktext, $before, $after, $comment );
    417 }
    418 
    419 /**
    420  * Generates semantic classes for each comment element.
    421  *
    422  * @since 2.7.0
    423  * @since 4.4.0 Added the ability for `$comment` to also accept a WP_Comment object.
    424  *
    425  * @param string|string[] $class    Optional. One or more classes to add to the class list.
    426  *                                  Default empty.
    427  * @param int|WP_Comment  $comment  Comment ID or WP_Comment object. Default current comment.
    428  * @param int|WP_Post     $post_id  Post ID or WP_Post object. Default current post.
    429  * @param bool            $echo     Optional. Whether to echo or return the output.
    430  *                                  Default true.
    431  * @return void|string Void if `$echo` argument is true, comment classes if `$echo` is false.
    432  */
    433 function comment_class( $class = '', $comment = null, $post_id = null, $echo = true ) {
    434 	// Separates classes with a single space, collates classes for comment DIV.
    435 	$class = 'class="' . implode( ' ', get_comment_class( $class, $comment, $post_id ) ) . '"';
    436 
    437 	if ( $echo ) {
    438 		echo $class;
    439 	} else {
    440 		return $class;
    441 	}
    442 }
    443 
    444 /**
    445  * Returns the classes for the comment div as an array.
    446  *
    447  * @since 2.7.0
    448  * @since 4.4.0 Added the ability for `$comment_id` to also accept a WP_Comment object.
    449  *
    450  * @global int $comment_alt
    451  * @global int $comment_depth
    452  * @global int $comment_thread_alt
    453  *
    454  * @param string|string[] $class      Optional. One or more classes to add to the class list. Default empty.
    455  * @param int|WP_Comment  $comment_id Comment ID or WP_Comment object. Default current comment.
    456  * @param int|WP_Post     $post_id    Post ID or WP_Post object. Default current post.
    457  * @return string[] An array of classes.
    458  */
    459 function get_comment_class( $class = '', $comment_id = null, $post_id = null ) {
    460 	global $comment_alt, $comment_depth, $comment_thread_alt;
    461 
    462 	$classes = array();
    463 
    464 	$comment = get_comment( $comment_id );
    465 	if ( ! $comment ) {
    466 		return $classes;
    467 	}
    468 
    469 	// Get the comment type (comment, trackback).
    470 	$classes[] = ( empty( $comment->comment_type ) ) ? 'comment' : $comment->comment_type;
    471 
    472 	// Add classes for comment authors that are registered users.
    473 	$user = $comment->user_id ? get_userdata( $comment->user_id ) : false;
    474 	if ( $user ) {
    475 		$classes[] = 'byuser';
    476 		$classes[] = 'comment-author-' . sanitize_html_class( $user->user_nicename, $comment->user_id );
    477 		// For comment authors who are the author of the post.
    478 		$post = get_post( $post_id );
    479 		if ( $post ) {
    480 			if ( $comment->user_id === $post->post_author ) {
    481 				$classes[] = 'bypostauthor';
    482 			}
    483 		}
    484 	}
    485 
    486 	if ( empty( $comment_alt ) ) {
    487 		$comment_alt = 0;
    488 	}
    489 	if ( empty( $comment_depth ) ) {
    490 		$comment_depth = 1;
    491 	}
    492 	if ( empty( $comment_thread_alt ) ) {
    493 		$comment_thread_alt = 0;
    494 	}
    495 
    496 	if ( $comment_alt % 2 ) {
    497 		$classes[] = 'odd';
    498 		$classes[] = 'alt';
    499 	} else {
    500 		$classes[] = 'even';
    501 	}
    502 
    503 	$comment_alt++;
    504 
    505 	// Alt for top-level comments.
    506 	if ( 1 == $comment_depth ) {
    507 		if ( $comment_thread_alt % 2 ) {
    508 			$classes[] = 'thread-odd';
    509 			$classes[] = 'thread-alt';
    510 		} else {
    511 			$classes[] = 'thread-even';
    512 		}
    513 		$comment_thread_alt++;
    514 	}
    515 
    516 	$classes[] = "depth-$comment_depth";
    517 
    518 	if ( ! empty( $class ) ) {
    519 		if ( ! is_array( $class ) ) {
    520 			$class = preg_split( '#\s+#', $class );
    521 		}
    522 		$classes = array_merge( $classes, $class );
    523 	}
    524 
    525 	$classes = array_map( 'esc_attr', $classes );
    526 
    527 	/**
    528 	 * Filters the returned CSS classes for the current comment.
    529 	 *
    530 	 * @since 2.7.0
    531 	 *
    532 	 * @param string[]    $classes    An array of comment classes.
    533 	 * @param string[]    $class      An array of additional classes added to the list.
    534 	 * @param int         $comment_id The comment ID.
    535 	 * @param WP_Comment  $comment    The comment object.
    536 	 * @param int|WP_Post $post_id    The post ID or WP_Post object.
    537 	 */
    538 	return apply_filters( 'comment_class', $classes, $class, $comment->comment_ID, $comment, $post_id );
    539 }
    540 
    541 /**
    542  * Retrieves the comment date of the current comment.
    543  *
    544  * @since 1.5.0
    545  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    546  *
    547  * @param string         $format     Optional. PHP date format. Defaults to the 'date_format' option.
    548  * @param int|WP_Comment $comment_ID WP_Comment or ID of the comment for which to get the date.
    549  *                                   Default current comment.
    550  * @return string The comment's date.
    551  */
    552 function get_comment_date( $format = '', $comment_ID = 0 ) {
    553 	$comment = get_comment( $comment_ID );
    554 
    555 	$_format = ! empty( $format ) ? $format : get_option( 'date_format' );
    556 
    557 	$date = mysql2date( $_format, $comment->comment_date );
    558 
    559 	/**
    560 	 * Filters the returned comment date.
    561 	 *
    562 	 * @since 1.5.0
    563 	 *
    564 	 * @param string|int $date    Formatted date string or Unix timestamp.
    565 	 * @param string     $format  PHP date format.
    566 	 * @param WP_Comment $comment The comment object.
    567 	 */
    568 	return apply_filters( 'get_comment_date', $date, $format, $comment );
    569 }
    570 
    571 /**
    572  * Displays the comment date of the current comment.
    573  *
    574  * @since 0.71
    575  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    576  *
    577  * @param string         $format     Optional. PHP date format. Defaults to the 'date_format' option.
    578  * @param int|WP_Comment $comment_ID WP_Comment or ID of the comment for which to print the date.
    579  *                                   Default current comment.
    580  */
    581 function comment_date( $format = '', $comment_ID = 0 ) {
    582 	echo get_comment_date( $format, $comment_ID );
    583 }
    584 
    585 /**
    586  * Retrieves the excerpt of the given comment.
    587  *
    588  * Returns a maximum of 20 words with an ellipsis appended if necessary.
    589  *
    590  * @since 1.5.0
    591  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    592  *
    593  * @param int|WP_Comment $comment_ID  WP_Comment or ID of the comment for which to get the excerpt.
    594  *                                    Default current comment.
    595  * @return string The possibly truncated comment excerpt.
    596  */
    597 function get_comment_excerpt( $comment_ID = 0 ) {
    598 	$comment = get_comment( $comment_ID );
    599 
    600 	if ( ! post_password_required( $comment->comment_post_ID ) ) {
    601 		$comment_text = strip_tags( str_replace( array( "\n", "\r" ), ' ', $comment->comment_content ) );
    602 	} else {
    603 		$comment_text = __( 'Password protected' );
    604 	}
    605 
    606 	/* translators: Maximum number of words used in a comment excerpt. */
    607 	$comment_excerpt_length = (int) _x( '20', 'comment_excerpt_length' );
    608 
    609 	/**
    610 	 * Filters the maximum number of words used in the comment excerpt.
    611 	 *
    612 	 * @since 4.4.0
    613 	 *
    614 	 * @param int $comment_excerpt_length The amount of words you want to display in the comment excerpt.
    615 	 */
    616 	$comment_excerpt_length = apply_filters( 'comment_excerpt_length', $comment_excerpt_length );
    617 
    618 	$excerpt = wp_trim_words( $comment_text, $comment_excerpt_length, '&hellip;' );
    619 
    620 	/**
    621 	 * Filters the retrieved comment excerpt.
    622 	 *
    623 	 * @since 1.5.0
    624 	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
    625 	 *
    626 	 * @param string     $excerpt    The comment excerpt text.
    627 	 * @param int        $comment_ID The comment ID.
    628 	 * @param WP_Comment $comment    The comment object.
    629 	 */
    630 	return apply_filters( 'get_comment_excerpt', $excerpt, $comment->comment_ID, $comment );
    631 }
    632 
    633 /**
    634  * Displays the excerpt of the current comment.
    635  *
    636  * @since 1.2.0
    637  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    638  *
    639  * @param int|WP_Comment $comment_ID  WP_Comment or ID of the comment for which to print the excerpt.
    640  *                                    Default current comment.
    641  */
    642 function comment_excerpt( $comment_ID = 0 ) {
    643 	$comment         = get_comment( $comment_ID );
    644 	$comment_excerpt = get_comment_excerpt( $comment );
    645 
    646 	/**
    647 	 * Filters the comment excerpt for display.
    648 	 *
    649 	 * @since 1.2.0
    650 	 * @since 4.1.0 The `$comment_ID` parameter was added.
    651 	 *
    652 	 * @param string $comment_excerpt The comment excerpt text.
    653 	 * @param int    $comment_ID      The comment ID.
    654 	 */
    655 	echo apply_filters( 'comment_excerpt', $comment_excerpt, $comment->comment_ID );
    656 }
    657 
    658 /**
    659  * Retrieves the comment ID of the current comment.
    660  *
    661  * @since 1.5.0
    662  *
    663  * @return int The comment ID.
    664  */
    665 function get_comment_ID() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
    666 	$comment = get_comment();
    667 
    668 	/**
    669 	 * Filters the returned comment ID.
    670 	 *
    671 	 * @since 1.5.0
    672 	 * @since 4.1.0 The `$comment_ID` parameter was added.
    673 	 *
    674 	 * @param int        $comment_ID The current comment ID.
    675 	 * @param WP_Comment $comment    The comment object.
    676 	 */
    677 	return apply_filters( 'get_comment_ID', $comment->comment_ID, $comment );  // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
    678 }
    679 
    680 /**
    681  * Displays the comment ID of the current comment.
    682  *
    683  * @since 0.71
    684  */
    685 function comment_ID() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
    686 	echo get_comment_ID();
    687 }
    688 
    689 /**
    690  * Retrieves the link to a given comment.
    691  *
    692  * @since 1.5.0
    693  * @since 4.4.0 Added the ability for `$comment` to also accept a WP_Comment object. Added `$cpage` argument.
    694  *
    695  * @see get_page_of_comment()
    696  *
    697  * @global WP_Rewrite $wp_rewrite      WordPress rewrite component.
    698  * @global bool       $in_comment_loop
    699  *
    700  * @param WP_Comment|int|null $comment Comment to retrieve. Default current comment.
    701  * @param array               $args {
    702  *     An array of optional arguments to override the defaults.
    703  *
    704  *     @type string     $type      Passed to get_page_of_comment().
    705  *     @type int        $page      Current page of comments, for calculating comment pagination.
    706  *     @type int        $per_page  Per-page value for comment pagination.
    707  *     @type int        $max_depth Passed to get_page_of_comment().
    708  *     @type int|string $cpage     Value to use for the comment's "comment-page" or "cpage" value.
    709  *                                 If provided, this value overrides any value calculated from `$page`
    710  *                                 and `$per_page`.
    711  * }
    712  * @return string The permalink to the given comment.
    713  */
    714 function get_comment_link( $comment = null, $args = array() ) {
    715 	global $wp_rewrite, $in_comment_loop;
    716 
    717 	$comment = get_comment( $comment );
    718 
    719 	// Back-compat.
    720 	if ( ! is_array( $args ) ) {
    721 		$args = array( 'page' => $args );
    722 	}
    723 
    724 	$defaults = array(
    725 		'type'      => 'all',
    726 		'page'      => '',
    727 		'per_page'  => '',
    728 		'max_depth' => '',
    729 		'cpage'     => null,
    730 	);
    731 	$args     = wp_parse_args( $args, $defaults );
    732 
    733 	$link = get_permalink( $comment->comment_post_ID );
    734 
    735 	// The 'cpage' param takes precedence.
    736 	if ( ! is_null( $args['cpage'] ) ) {
    737 		$cpage = $args['cpage'];
    738 
    739 		// No 'cpage' is provided, so we calculate one.
    740 	} else {
    741 		if ( '' === $args['per_page'] && get_option( 'page_comments' ) ) {
    742 			$args['per_page'] = get_option( 'comments_per_page' );
    743 		}
    744 
    745 		if ( empty( $args['per_page'] ) ) {
    746 			$args['per_page'] = 0;
    747 			$args['page']     = 0;
    748 		}
    749 
    750 		$cpage = $args['page'];
    751 
    752 		if ( '' == $cpage ) {
    753 			if ( ! empty( $in_comment_loop ) ) {
    754 				$cpage = get_query_var( 'cpage' );
    755 			} else {
    756 				// Requires a database hit, so we only do it when we can't figure out from context.
    757 				$cpage = get_page_of_comment( $comment->comment_ID, $args );
    758 			}
    759 		}
    760 
    761 		/*
    762 		 * If the default page displays the oldest comments, the permalinks for comments on the default page
    763 		 * do not need a 'cpage' query var.
    764 		 */
    765 		if ( 'oldest' === get_option( 'default_comments_page' ) && 1 === $cpage ) {
    766 			$cpage = '';
    767 		}
    768 	}
    769 
    770 	if ( $cpage && get_option( 'page_comments' ) ) {
    771 		if ( $wp_rewrite->using_permalinks() ) {
    772 			if ( $cpage ) {
    773 				$link = trailingslashit( $link ) . $wp_rewrite->comments_pagination_base . '-' . $cpage;
    774 			}
    775 
    776 			$link = user_trailingslashit( $link, 'comment' );
    777 		} elseif ( $cpage ) {
    778 			$link = add_query_arg( 'cpage', $cpage, $link );
    779 		}
    780 	}
    781 
    782 	if ( $wp_rewrite->using_permalinks() ) {
    783 		$link = user_trailingslashit( $link, 'comment' );
    784 	}
    785 
    786 	$link = $link . '#comment-' . $comment->comment_ID;
    787 
    788 	/**
    789 	 * Filters the returned single comment permalink.
    790 	 *
    791 	 * @since 2.8.0
    792 	 * @since 4.4.0 Added the `$cpage` parameter.
    793 	 *
    794 	 * @see get_page_of_comment()
    795 	 *
    796 	 * @param string     $link    The comment permalink with '#comment-$id' appended.
    797 	 * @param WP_Comment $comment The current comment object.
    798 	 * @param array      $args    An array of arguments to override the defaults.
    799 	 * @param int        $cpage   The calculated 'cpage' value.
    800 	 */
    801 	return apply_filters( 'get_comment_link', $link, $comment, $args, $cpage );
    802 }
    803 
    804 /**
    805  * Retrieves the link to the current post comments.
    806  *
    807  * @since 1.5.0
    808  *
    809  * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is global $post.
    810  * @return string The link to the comments.
    811  */
    812 function get_comments_link( $post_id = 0 ) {
    813 	$hash          = get_comments_number( $post_id ) ? '#comments' : '#respond';
    814 	$comments_link = get_permalink( $post_id ) . $hash;
    815 
    816 	/**
    817 	 * Filters the returned post comments permalink.
    818 	 *
    819 	 * @since 3.6.0
    820 	 *
    821 	 * @param string      $comments_link Post comments permalink with '#comments' appended.
    822 	 * @param int|WP_Post $post_id       Post ID or WP_Post object.
    823 	 */
    824 	return apply_filters( 'get_comments_link', $comments_link, $post_id );
    825 }
    826 
    827 /**
    828  * Displays the link to the current post comments.
    829  *
    830  * @since 0.71
    831  *
    832  * @param string $deprecated   Not Used.
    833  * @param string $deprecated_2 Not Used.
    834  */
    835 function comments_link( $deprecated = '', $deprecated_2 = '' ) {
    836 	if ( ! empty( $deprecated ) ) {
    837 		_deprecated_argument( __FUNCTION__, '0.72' );
    838 	}
    839 	if ( ! empty( $deprecated_2 ) ) {
    840 		_deprecated_argument( __FUNCTION__, '1.3.0' );
    841 	}
    842 	echo esc_url( get_comments_link() );
    843 }
    844 
    845 /**
    846  * Retrieves the amount of comments a post has.
    847  *
    848  * @since 1.5.0
    849  *
    850  * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is the global `$post`.
    851  * @return string|int If the post exists, a numeric string representing the number of comments
    852  *                    the post has, otherwise 0.
    853  */
    854 function get_comments_number( $post_id = 0 ) {
    855 	$post = get_post( $post_id );
    856 
    857 	if ( ! $post ) {
    858 		$count = 0;
    859 	} else {
    860 		$count   = $post->comment_count;
    861 		$post_id = $post->ID;
    862 	}
    863 
    864 	/**
    865 	 * Filters the returned comment count for a post.
    866 	 *
    867 	 * @since 1.5.0
    868 	 *
    869 	 * @param string|int $count   A string representing the number of comments a post has, otherwise 0.
    870 	 * @param int        $post_id Post ID.
    871 	 */
    872 	return apply_filters( 'get_comments_number', $count, $post_id );
    873 }
    874 
    875 /**
    876  * Displays the language string for the number of comments the current post has.
    877  *
    878  * @since 0.71
    879  * @since 5.4.0 The `$deprecated` parameter was changed to `$post_id`.
    880  *
    881  * @param string|false $zero    Optional. Text for no comments. Default false.
    882  * @param string|false $one     Optional. Text for one comment. Default false.
    883  * @param string|false $more    Optional. Text for more than one comment. Default false.
    884  * @param int|WP_Post  $post_id Optional. Post ID or WP_Post object. Default is the global `$post`.
    885  */
    886 function comments_number( $zero = false, $one = false, $more = false, $post_id = 0 ) {
    887 	echo get_comments_number_text( $zero, $one, $more, $post_id );
    888 }
    889 
    890 /**
    891  * Displays the language string for the number of comments the current post has.
    892  *
    893  * @since 4.0.0
    894  * @since 5.4.0 Added the `$post_id` parameter to allow using the function outside of the loop.
    895  *
    896  * @param string      $zero    Optional. Text for no comments. Default false.
    897  * @param string      $one     Optional. Text for one comment. Default false.
    898  * @param string      $more    Optional. Text for more than one comment. Default false.
    899  * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is the global `$post`.
    900  * @return string Language string for the number of comments a post has.
    901  */
    902 function get_comments_number_text( $zero = false, $one = false, $more = false, $post_id = 0 ) {
    903 	$number = get_comments_number( $post_id );
    904 
    905 	if ( $number > 1 ) {
    906 		if ( false === $more ) {
    907 			/* translators: %s: Number of comments. */
    908 			$output = sprintf( _n( '%s Comment', '%s Comments', $number ), number_format_i18n( $number ) );
    909 		} else {
    910 			// % Comments
    911 			/*
    912 			 * translators: If comment number in your language requires declension,
    913 			 * translate this to 'on'. Do not translate into your own language.
    914 			 */
    915 			if ( 'on' === _x( 'off', 'Comment number declension: on or off' ) ) {
    916 				$text = preg_replace( '#<span class="screen-reader-text">.+?</span>#', '', $more );
    917 				$text = preg_replace( '/&.+?;/', '', $text ); // Kill entities.
    918 				$text = trim( strip_tags( $text ), '% ' );
    919 
    920 				// Replace '% Comments' with a proper plural form.
    921 				if ( $text && ! preg_match( '/[0-9]+/', $text ) && false !== strpos( $more, '%' ) ) {
    922 					/* translators: %s: Number of comments. */
    923 					$new_text = _n( '%s Comment', '%s Comments', $number );
    924 					$new_text = trim( sprintf( $new_text, '' ) );
    925 
    926 					$more = str_replace( $text, $new_text, $more );
    927 					if ( false === strpos( $more, '%' ) ) {
    928 						$more = '% ' . $more;
    929 					}
    930 				}
    931 			}
    932 
    933 			$output = str_replace( '%', number_format_i18n( $number ), $more );
    934 		}
    935 	} elseif ( 0 == $number ) {
    936 		$output = ( false === $zero ) ? __( 'No Comments' ) : $zero;
    937 	} else { // Must be one.
    938 		$output = ( false === $one ) ? __( '1 Comment' ) : $one;
    939 	}
    940 	/**
    941 	 * Filters the comments count for display.
    942 	 *
    943 	 * @since 1.5.0
    944 	 *
    945 	 * @see _n()
    946 	 *
    947 	 * @param string $output A translatable string formatted based on whether the count
    948 	 *                       is equal to 0, 1, or 1+.
    949 	 * @param int    $number The number of post comments.
    950 	 */
    951 	return apply_filters( 'comments_number', $output, $number );
    952 }
    953 
    954 /**
    955  * Retrieves the text of the current comment.
    956  *
    957  * @since 1.5.0
    958  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
    959  * @since 5.4.0 Added 'In reply to %s.' prefix to child comments in comments feed.
    960  *
    961  * @see Walker_Comment::comment()
    962  *
    963  * @param int|WP_Comment $comment_ID WP_Comment or ID of the comment for which to get the text.
    964  *                                   Default current comment.
    965  * @param array          $args       Optional. An array of arguments. Default empty array.
    966  * @return string The comment content.
    967  */
    968 function get_comment_text( $comment_ID = 0, $args = array() ) {
    969 	$comment = get_comment( $comment_ID );
    970 
    971 	$comment_content = $comment->comment_content;
    972 
    973 	if ( is_comment_feed() && $comment->comment_parent ) {
    974 		$parent = get_comment( $comment->comment_parent );
    975 		if ( $parent ) {
    976 			$parent_link = esc_url( get_comment_link( $parent ) );
    977 			$name        = get_comment_author( $parent );
    978 
    979 			$comment_content = sprintf(
    980 				/* translators: %s: Comment link. */
    981 				ent2ncr( __( 'In reply to %s.' ) ),
    982 				'<a href="' . $parent_link . '">' . $name . '</a>'
    983 			) . "\n\n" . $comment_content;
    984 		}
    985 	}
    986 
    987 	/**
    988 	 * Filters the text of a comment.
    989 	 *
    990 	 * @since 1.5.0
    991 	 *
    992 	 * @see Walker_Comment::comment()
    993 	 *
    994 	 * @param string     $comment_content Text of the comment.
    995 	 * @param WP_Comment $comment         The comment object.
    996 	 * @param array      $args            An array of arguments.
    997 	 */
    998 	return apply_filters( 'get_comment_text', $comment_content, $comment, $args );
    999 }
   1000 
   1001 /**
   1002  * Displays the text of the current comment.
   1003  *
   1004  * @since 0.71
   1005  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
   1006  *
   1007  * @see Walker_Comment::comment()
   1008  *
   1009  * @param int|WP_Comment $comment_ID WP_Comment or ID of the comment for which to print the text.
   1010  *                                   Default current comment.
   1011  * @param array          $args       Optional. An array of arguments. Default empty array.
   1012  */
   1013 function comment_text( $comment_ID = 0, $args = array() ) {
   1014 	$comment = get_comment( $comment_ID );
   1015 
   1016 	$comment_text = get_comment_text( $comment, $args );
   1017 	/**
   1018 	 * Filters the text of a comment to be displayed.
   1019 	 *
   1020 	 * @since 1.2.0
   1021 	 *
   1022 	 * @see Walker_Comment::comment()
   1023 	 *
   1024 	 * @param string          $comment_text Text of the current comment.
   1025 	 * @param WP_Comment|null $comment      The comment object. Null if not found.
   1026 	 * @param array           $args         An array of arguments.
   1027 	 */
   1028 	echo apply_filters( 'comment_text', $comment_text, $comment, $args );
   1029 }
   1030 
   1031 /**
   1032  * Retrieves the comment time of the current comment.
   1033  *
   1034  * @since 1.5.0
   1035  *
   1036  * @param string $format    Optional. PHP time format. Defaults to the 'time_format' option.
   1037  * @param bool   $gmt       Optional. Whether to use the GMT date. Default false.
   1038  * @param bool   $translate Optional. Whether to translate the time (for use in feeds).
   1039  *                          Default true.
   1040  * @return string The formatted time.
   1041  */
   1042 function get_comment_time( $format = '', $gmt = false, $translate = true ) {
   1043 	$comment = get_comment();
   1044 
   1045 	$comment_date = $gmt ? $comment->comment_date_gmt : $comment->comment_date;
   1046 
   1047 	$_format = ! empty( $format ) ? $format : get_option( 'time_format' );
   1048 
   1049 	$date = mysql2date( $_format, $comment_date, $translate );
   1050 
   1051 	/**
   1052 	 * Filters the returned comment time.
   1053 	 *
   1054 	 * @since 1.5.0
   1055 	 *
   1056 	 * @param string|int $date      The comment time, formatted as a date string or Unix timestamp.
   1057 	 * @param string     $format    PHP date format.
   1058 	 * @param bool       $gmt       Whether the GMT date is in use.
   1059 	 * @param bool       $translate Whether the time is translated.
   1060 	 * @param WP_Comment $comment   The comment object.
   1061 	 */
   1062 	return apply_filters( 'get_comment_time', $date, $format, $gmt, $translate, $comment );
   1063 }
   1064 
   1065 /**
   1066  * Displays the comment time of the current comment.
   1067  *
   1068  * @since 0.71
   1069  *
   1070  * @param string $format Optional. PHP time format. Defaults to the 'time_format' option.
   1071  */
   1072 function comment_time( $format = '' ) {
   1073 	echo get_comment_time( $format );
   1074 }
   1075 
   1076 /**
   1077  * Retrieves the comment type of the current comment.
   1078  *
   1079  * @since 1.5.0
   1080  * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
   1081  *
   1082  * @param int|WP_Comment $comment_ID Optional. WP_Comment or ID of the comment for which to get the type.
   1083  *                                   Default current comment.
   1084  * @return string The comment type.
   1085  */
   1086 function get_comment_type( $comment_ID = 0 ) {
   1087 	$comment = get_comment( $comment_ID );
   1088 
   1089 	if ( '' === $comment->comment_type ) {
   1090 		$comment->comment_type = 'comment';
   1091 	}
   1092 
   1093 	/**
   1094 	 * Filters the returned comment type.
   1095 	 *
   1096 	 * @since 1.5.0
   1097 	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
   1098 	 *
   1099 	 * @param string     $comment_type The type of comment, such as 'comment', 'pingback', or 'trackback'.
   1100 	 * @param int        $comment_ID   The comment ID.
   1101 	 * @param WP_Comment $comment      The comment object.
   1102 	 */
   1103 	return apply_filters( 'get_comment_type', $comment->comment_type, $comment->comment_ID, $comment );
   1104 }
   1105 
   1106 /**
   1107  * Displays the comment type of the current comment.
   1108  *
   1109  * @since 0.71
   1110  *
   1111  * @param string|false $commenttxt   Optional. String to display for comment type. Default false.
   1112  * @param string|false $trackbacktxt Optional. String to display for trackback type. Default false.
   1113  * @param string|false $pingbacktxt  Optional. String to display for pingback type. Default false.
   1114  */
   1115 function comment_type( $commenttxt = false, $trackbacktxt = false, $pingbacktxt = false ) {
   1116 	if ( false === $commenttxt ) {
   1117 		$commenttxt = _x( 'Comment', 'noun' );
   1118 	}
   1119 	if ( false === $trackbacktxt ) {
   1120 		$trackbacktxt = __( 'Trackback' );
   1121 	}
   1122 	if ( false === $pingbacktxt ) {
   1123 		$pingbacktxt = __( 'Pingback' );
   1124 	}
   1125 	$type = get_comment_type();
   1126 	switch ( $type ) {
   1127 		case 'trackback':
   1128 			echo $trackbacktxt;
   1129 			break;
   1130 		case 'pingback':
   1131 			echo $pingbacktxt;
   1132 			break;
   1133 		default:
   1134 			echo $commenttxt;
   1135 	}
   1136 }
   1137 
   1138 /**
   1139  * Retrieves the current post's trackback URL.
   1140  *
   1141  * There is a check to see if permalink's have been enabled and if so, will
   1142  * retrieve the pretty path. If permalinks weren't enabled, the ID of the
   1143  * current post is used and appended to the correct page to go to.
   1144  *
   1145  * @since 1.5.0
   1146  *
   1147  * @return string The trackback URL after being filtered.
   1148  */
   1149 function get_trackback_url() {
   1150 	if ( get_option( 'permalink_structure' ) ) {
   1151 		$tb_url = trailingslashit( get_permalink() ) . user_trailingslashit( 'trackback', 'single_trackback' );
   1152 	} else {
   1153 		$tb_url = get_option( 'siteurl' ) . '/wp-trackback.php?p=' . get_the_ID();
   1154 	}
   1155 
   1156 	/**
   1157 	 * Filters the returned trackback URL.
   1158 	 *
   1159 	 * @since 2.2.0
   1160 	 *
   1161 	 * @param string $tb_url The trackback URL.
   1162 	 */
   1163 	return apply_filters( 'trackback_url', $tb_url );
   1164 }
   1165 
   1166 /**
   1167  * Displays the current post's trackback URL.
   1168  *
   1169  * @since 0.71
   1170  *
   1171  * @param bool $deprecated_echo Not used.
   1172  * @return void|string Should only be used to echo the trackback URL, use get_trackback_url()
   1173  *                     for the result instead.
   1174  */
   1175 function trackback_url( $deprecated_echo = true ) {
   1176 	if ( true !== $deprecated_echo ) {
   1177 		_deprecated_argument(
   1178 			__FUNCTION__,
   1179 			'2.5.0',
   1180 			sprintf(
   1181 				/* translators: %s: get_trackback_url() */
   1182 				__( 'Use %s instead if you do not want the value echoed.' ),
   1183 				'<code>get_trackback_url()</code>'
   1184 			)
   1185 		);
   1186 	}
   1187 
   1188 	if ( $deprecated_echo ) {
   1189 		echo get_trackback_url();
   1190 	} else {
   1191 		return get_trackback_url();
   1192 	}
   1193 }
   1194 
   1195 /**
   1196  * Generates and displays the RDF for the trackback information of current post.
   1197  *
   1198  * Deprecated in 3.0.0, and restored in 3.0.1.
   1199  *
   1200  * @since 0.71
   1201  *
   1202  * @param int|string $deprecated Not used (Was $timezone = 0).
   1203  */
   1204 function trackback_rdf( $deprecated = '' ) {
   1205 	if ( ! empty( $deprecated ) ) {
   1206 		_deprecated_argument( __FUNCTION__, '2.5.0' );
   1207 	}
   1208 
   1209 	if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && false !== stripos( $_SERVER['HTTP_USER_AGENT'], 'W3C_Validator' ) ) {
   1210 		return;
   1211 	}
   1212 
   1213 	echo '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   1214 			xmlns:dc="http://purl.org/dc/elements/1.1/"
   1215 			xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
   1216 		<rdf:Description rdf:about="';
   1217 	the_permalink();
   1218 	echo '"' . "\n";
   1219 	echo '    dc:identifier="';
   1220 	the_permalink();
   1221 	echo '"' . "\n";
   1222 	echo '    dc:title="' . str_replace( '--', '&#x2d;&#x2d;', wptexturize( strip_tags( get_the_title() ) ) ) . '"' . "\n";
   1223 	echo '    trackback:ping="' . get_trackback_url() . '"' . " />\n";
   1224 	echo '</rdf:RDF>';
   1225 }
   1226 
   1227 /**
   1228  * Determines whether the current post is open for comments.
   1229  *
   1230  * For more information on this and similar theme functions, check out
   1231  * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
   1232  * Conditional Tags} article in the Theme Developer Handbook.
   1233  *
   1234  * @since 1.5.0
   1235  *
   1236  * @param int|WP_Post $post_id Post ID or WP_Post object. Default current post.
   1237  * @return bool True if the comments are open.
   1238  */
   1239 function comments_open( $post_id = null ) {
   1240 
   1241 	$_post = get_post( $post_id );
   1242 
   1243 	$post_id = $_post ? $_post->ID : 0;
   1244 	$open    = ( 'open' === $_post->comment_status );
   1245 
   1246 	/**
   1247 	 * Filters whether the current post is open for comments.
   1248 	 *
   1249 	 * @since 2.5.0
   1250 	 *
   1251 	 * @param bool $open    Whether the current post is open for comments.
   1252 	 * @param int  $post_id The post ID.
   1253 	 */
   1254 	return apply_filters( 'comments_open', $open, $post_id );
   1255 }
   1256 
   1257 /**
   1258  * Determines whether the current post is open for pings.
   1259  *
   1260  * For more information on this and similar theme functions, check out
   1261  * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
   1262  * Conditional Tags} article in the Theme Developer Handbook.
   1263  *
   1264  * @since 1.5.0
   1265  *
   1266  * @param int|WP_Post $post_id Post ID or WP_Post object. Default current post.
   1267  * @return bool True if pings are accepted
   1268  */
   1269 function pings_open( $post_id = null ) {
   1270 
   1271 	$_post = get_post( $post_id );
   1272 
   1273 	$post_id = $_post ? $_post->ID : 0;
   1274 	$open    = ( 'open' === $_post->ping_status );
   1275 
   1276 	/**
   1277 	 * Filters whether the current post is open for pings.
   1278 	 *
   1279 	 * @since 2.5.0
   1280 	 *
   1281 	 * @param bool $open    Whether the current post is open for pings.
   1282 	 * @param int  $post_id The post ID.
   1283 	 */
   1284 	return apply_filters( 'pings_open', $open, $post_id );
   1285 }
   1286 
   1287 /**
   1288  * Displays form token for unfiltered comments.
   1289  *
   1290  * Will only display nonce token if the current user has permissions for
   1291  * unfiltered html. Won't display the token for other users.
   1292  *
   1293  * The function was backported to 2.0.10 and was added to versions 2.1.3 and
   1294  * above. Does not exist in versions prior to 2.0.10 in the 2.0 branch and in
   1295  * the 2.1 branch, prior to 2.1.3. Technically added in 2.2.0.
   1296  *
   1297  * Backported to 2.0.10.
   1298  *
   1299  * @since 2.1.3
   1300  */
   1301 function wp_comment_form_unfiltered_html_nonce() {
   1302 	$post    = get_post();
   1303 	$post_id = $post ? $post->ID : 0;
   1304 
   1305 	if ( current_user_can( 'unfiltered_html' ) ) {
   1306 		wp_nonce_field( 'unfiltered-html-comment_' . $post_id, '_wp_unfiltered_html_comment_disabled', false );
   1307 		echo "<script>(function(){if(window===window.parent){document.getElementById('_wp_unfiltered_html_comment_disabled').name='_wp_unfiltered_html_comment';}})();</script>\n";
   1308 	}
   1309 }
   1310 
   1311 /**
   1312  * Loads the comment template specified in $file.
   1313  *
   1314  * Will not display the comments template if not on single post or page, or if
   1315  * the post does not have comments.
   1316  *
   1317  * Uses the WordPress database object to query for the comments. The comments
   1318  * are passed through the {@see 'comments_array'} filter hook with the list of comments
   1319  * and the post ID respectively.
   1320  *
   1321  * The `$file` path is passed through a filter hook called {@see 'comments_template'},
   1322  * which includes the TEMPLATEPATH and $file combined. Tries the $filtered path
   1323  * first and if it fails it will require the default comment template from the
   1324  * default theme. If either does not exist, then the WordPress process will be
   1325  * halted. It is advised for that reason, that the default theme is not deleted.
   1326  *
   1327  * Will not try to get the comments if the post has none.
   1328  *
   1329  * @since 1.5.0
   1330  *
   1331  * @global WP_Query   $wp_query         WordPress Query object.
   1332  * @global WP_Post    $post             Global post object.
   1333  * @global wpdb       $wpdb             WordPress database abstraction object.
   1334  * @global int        $id
   1335  * @global WP_Comment $comment          Global comment object.
   1336  * @global string     $user_login
   1337  * @global string     $user_identity
   1338  * @global bool       $overridden_cpage
   1339  * @global bool       $withcomments
   1340  *
   1341  * @param string $file              Optional. The file to load. Default '/comments.php'.
   1342  * @param bool   $separate_comments Optional. Whether to separate the comments by comment type.
   1343  *                                  Default false.
   1344  */
   1345 function comments_template( $file = '/comments.php', $separate_comments = false ) {
   1346 	global $wp_query, $withcomments, $post, $wpdb, $id, $comment, $user_login, $user_identity, $overridden_cpage;
   1347 
   1348 	if ( ! ( is_single() || is_page() || $withcomments ) || empty( $post ) ) {
   1349 		return;
   1350 	}
   1351 
   1352 	if ( empty( $file ) ) {
   1353 		$file = '/comments.php';
   1354 	}
   1355 
   1356 	$req = get_option( 'require_name_email' );
   1357 
   1358 	/*
   1359 	 * Comment author information fetched from the comment cookies.
   1360 	 */
   1361 	$commenter = wp_get_current_commenter();
   1362 
   1363 	/*
   1364 	 * The name of the current comment author escaped for use in attributes.
   1365 	 * Escaped by sanitize_comment_cookies().
   1366 	 */
   1367 	$comment_author = $commenter['comment_author'];
   1368 
   1369 	/*
   1370 	 * The email address of the current comment author escaped for use in attributes.
   1371 	 * Escaped by sanitize_comment_cookies().
   1372 	 */
   1373 	$comment_author_email = $commenter['comment_author_email'];
   1374 
   1375 	/*
   1376 	 * The URL of the current comment author escaped for use in attributes.
   1377 	 */
   1378 	$comment_author_url = esc_url( $commenter['comment_author_url'] );
   1379 
   1380 	$comment_args = array(
   1381 		'orderby'                   => 'comment_date_gmt',
   1382 		'order'                     => 'ASC',
   1383 		'status'                    => 'approve',
   1384 		'post_id'                   => $post->ID,
   1385 		'no_found_rows'             => false,
   1386 		'update_comment_meta_cache' => false, // We lazy-load comment meta for performance.
   1387 	);
   1388 
   1389 	if ( get_option( 'thread_comments' ) ) {
   1390 		$comment_args['hierarchical'] = 'threaded';
   1391 	} else {
   1392 		$comment_args['hierarchical'] = false;
   1393 	}
   1394 
   1395 	if ( is_user_logged_in() ) {
   1396 		$comment_args['include_unapproved'] = array( get_current_user_id() );
   1397 	} else {
   1398 		$unapproved_email = wp_get_unapproved_comment_author_email();
   1399 
   1400 		if ( $unapproved_email ) {
   1401 			$comment_args['include_unapproved'] = array( $unapproved_email );
   1402 		}
   1403 	}
   1404 
   1405 	$per_page = 0;
   1406 	if ( get_option( 'page_comments' ) ) {
   1407 		$per_page = (int) get_query_var( 'comments_per_page' );
   1408 		if ( 0 === $per_page ) {
   1409 			$per_page = (int) get_option( 'comments_per_page' );
   1410 		}
   1411 
   1412 		$comment_args['number'] = $per_page;
   1413 		$page                   = (int) get_query_var( 'cpage' );
   1414 
   1415 		if ( $page ) {
   1416 			$comment_args['offset'] = ( $page - 1 ) * $per_page;
   1417 		} elseif ( 'oldest' === get_option( 'default_comments_page' ) ) {
   1418 			$comment_args['offset'] = 0;
   1419 		} else {
   1420 			// If fetching the first page of 'newest', we need a top-level comment count.
   1421 			$top_level_query = new WP_Comment_Query();
   1422 			$top_level_args  = array(
   1423 				'count'   => true,
   1424 				'orderby' => false,
   1425 				'post_id' => $post->ID,
   1426 				'status'  => 'approve',
   1427 			);
   1428 
   1429 			if ( $comment_args['hierarchical'] ) {
   1430 				$top_level_args['parent'] = 0;
   1431 			}
   1432 
   1433 			if ( isset( $comment_args['include_unapproved'] ) ) {
   1434 				$top_level_args['include_unapproved'] = $comment_args['include_unapproved'];
   1435 			}
   1436 
   1437 			/**
   1438 			 * Filters the arguments used in the top level comments query.
   1439 			 *
   1440 			 * @since 5.6.0
   1441 			 *
   1442 			 * @see WP_Comment_Query::__construct()
   1443 			 *
   1444 			 * @param array $top_level_args {
   1445 			 *     The top level query arguments for the comments template.
   1446 			 *
   1447 			 *     @type bool         $count   Whether to return a comment count.
   1448 			 *     @type string|array $orderby The field(s) to order by.
   1449 			 *     @type int          $post_id The post ID.
   1450 			 *     @type string|array $status  The comment status to limit results by.
   1451 			 * }
   1452 			 */
   1453 			$top_level_args = apply_filters( 'comments_template_top_level_query_args', $top_level_args );
   1454 
   1455 			$top_level_count = $top_level_query->query( $top_level_args );
   1456 
   1457 			$comment_args['offset'] = ( ceil( $top_level_count / $per_page ) - 1 ) * $per_page;
   1458 		}
   1459 	}
   1460 
   1461 	/**
   1462 	 * Filters the arguments used to query comments in comments_template().
   1463 	 *
   1464 	 * @since 4.5.0
   1465 	 *
   1466 	 * @see WP_Comment_Query::__construct()
   1467 	 *
   1468 	 * @param array $comment_args {
   1469 	 *     Array of WP_Comment_Query arguments.
   1470 	 *
   1471 	 *     @type string|array $orderby                   Field(s) to order by.
   1472 	 *     @type string       $order                     Order of results. Accepts 'ASC' or 'DESC'.
   1473 	 *     @type string       $status                    Comment status.
   1474 	 *     @type array        $include_unapproved        Array of IDs or email addresses whose unapproved comments
   1475 	 *                                                   will be included in results.
   1476 	 *     @type int          $post_id                   ID of the post.
   1477 	 *     @type bool         $no_found_rows             Whether to refrain from querying for found rows.
   1478 	 *     @type bool         $update_comment_meta_cache Whether to prime cache for comment meta.
   1479 	 *     @type bool|string  $hierarchical              Whether to query for comments hierarchically.
   1480 	 *     @type int          $offset                    Comment offset.
   1481 	 *     @type int          $number                    Number of comments to fetch.
   1482 	 * }
   1483 	 */
   1484 	$comment_args = apply_filters( 'comments_template_query_args', $comment_args );
   1485 
   1486 	$comment_query = new WP_Comment_Query( $comment_args );
   1487 	$_comments     = $comment_query->comments;
   1488 
   1489 	// Trees must be flattened before they're passed to the walker.
   1490 	if ( $comment_args['hierarchical'] ) {
   1491 		$comments_flat = array();
   1492 		foreach ( $_comments as $_comment ) {
   1493 			$comments_flat[]  = $_comment;
   1494 			$comment_children = $_comment->get_children(
   1495 				array(
   1496 					'format'  => 'flat',
   1497 					'status'  => $comment_args['status'],
   1498 					'orderby' => $comment_args['orderby'],
   1499 				)
   1500 			);
   1501 
   1502 			foreach ( $comment_children as $comment_child ) {
   1503 				$comments_flat[] = $comment_child;
   1504 			}
   1505 		}
   1506 	} else {
   1507 		$comments_flat = $_comments;
   1508 	}
   1509 
   1510 	/**
   1511 	 * Filters the comments array.
   1512 	 *
   1513 	 * @since 2.1.0
   1514 	 *
   1515 	 * @param array $comments Array of comments supplied to the comments template.
   1516 	 * @param int   $post_ID  Post ID.
   1517 	 */
   1518 	$wp_query->comments = apply_filters( 'comments_array', $comments_flat, $post->ID );
   1519 
   1520 	$comments                        = &$wp_query->comments;
   1521 	$wp_query->comment_count         = count( $wp_query->comments );
   1522 	$wp_query->max_num_comment_pages = $comment_query->max_num_pages;
   1523 
   1524 	if ( $separate_comments ) {
   1525 		$wp_query->comments_by_type = separate_comments( $comments );
   1526 		$comments_by_type           = &$wp_query->comments_by_type;
   1527 	} else {
   1528 		$wp_query->comments_by_type = array();
   1529 	}
   1530 
   1531 	$overridden_cpage = false;
   1532 
   1533 	if ( '' == get_query_var( 'cpage' ) && $wp_query->max_num_comment_pages > 1 ) {
   1534 		set_query_var( 'cpage', 'newest' === get_option( 'default_comments_page' ) ? get_comment_pages_count() : 1 );
   1535 		$overridden_cpage = true;
   1536 	}
   1537 
   1538 	if ( ! defined( 'COMMENTS_TEMPLATE' ) ) {
   1539 		define( 'COMMENTS_TEMPLATE', true );
   1540 	}
   1541 
   1542 	$theme_template = STYLESHEETPATH . $file;
   1543 
   1544 	/**
   1545 	 * Filters the path to the theme template file used for the comments template.
   1546 	 *
   1547 	 * @since 1.5.1
   1548 	 *
   1549 	 * @param string $theme_template The path to the theme template file.
   1550 	 */
   1551 	$include = apply_filters( 'comments_template', $theme_template );
   1552 
   1553 	if ( file_exists( $include ) ) {
   1554 		require $include;
   1555 	} elseif ( file_exists( TEMPLATEPATH . $file ) ) {
   1556 		require TEMPLATEPATH . $file;
   1557 	} else { // Backward compat code will be removed in a future release.
   1558 		require ABSPATH . WPINC . '/theme-compat/comments.php';
   1559 	}
   1560 }
   1561 
   1562 /**
   1563  * Displays the link to the comments for the current post ID.
   1564  *
   1565  * @since 0.71
   1566  *
   1567  * @param false|string $zero      Optional. String to display when no comments. Default false.
   1568  * @param false|string $one       Optional. String to display when only one comment is available. Default false.
   1569  * @param false|string $more      Optional. String to display when there are more than one comment. Default false.
   1570  * @param string       $css_class Optional. CSS class to use for comments. Default empty.
   1571  * @param false|string $none      Optional. String to display when comments have been turned off. Default false.
   1572  */
   1573 function comments_popup_link( $zero = false, $one = false, $more = false, $css_class = '', $none = false ) {
   1574 	$post_id    = get_the_ID();
   1575 	$post_title = get_the_title();
   1576 	$number     = get_comments_number( $post_id );
   1577 
   1578 	if ( false === $zero ) {
   1579 		/* translators: %s: Post title. */
   1580 		$zero = sprintf( __( 'No Comments<span class="screen-reader-text"> on %s</span>' ), $post_title );
   1581 	}
   1582 
   1583 	if ( false === $one ) {
   1584 		/* translators: %s: Post title. */
   1585 		$one = sprintf( __( '1 Comment<span class="screen-reader-text"> on %s</span>' ), $post_title );
   1586 	}
   1587 
   1588 	if ( false === $more ) {
   1589 		/* translators: 1: Number of comments, 2: Post title. */
   1590 		$more = _n( '%1$s Comment<span class="screen-reader-text"> on %2$s</span>', '%1$s Comments<span class="screen-reader-text"> on %2$s</span>', $number );
   1591 		$more = sprintf( $more, number_format_i18n( $number ), $post_title );
   1592 	}
   1593 
   1594 	if ( false === $none ) {
   1595 		/* translators: %s: Post title. */
   1596 		$none = sprintf( __( 'Comments Off<span class="screen-reader-text"> on %s</span>' ), $post_title );
   1597 	}
   1598 
   1599 	if ( 0 == $number && ! comments_open() && ! pings_open() ) {
   1600 		echo '<span' . ( ( ! empty( $css_class ) ) ? ' class="' . esc_attr( $css_class ) . '"' : '' ) . '>' . $none . '</span>';
   1601 		return;
   1602 	}
   1603 
   1604 	if ( post_password_required() ) {
   1605 		_e( 'Enter your password to view comments.' );
   1606 		return;
   1607 	}
   1608 
   1609 	echo '<a href="';
   1610 	if ( 0 == $number ) {
   1611 		$respond_link = get_permalink() . '#respond';
   1612 		/**
   1613 		 * Filters the respond link when a post has no comments.
   1614 		 *
   1615 		 * @since 4.4.0
   1616 		 *
   1617 		 * @param string $respond_link The default response link.
   1618 		 * @param int    $post_id      The post ID.
   1619 		 */
   1620 		echo apply_filters( 'respond_link', $respond_link, $post_id );
   1621 	} else {
   1622 		comments_link();
   1623 	}
   1624 	echo '"';
   1625 
   1626 	if ( ! empty( $css_class ) ) {
   1627 		echo ' class="' . $css_class . '" ';
   1628 	}
   1629 
   1630 	$attributes = '';
   1631 	/**
   1632 	 * Filters the comments link attributes for display.
   1633 	 *
   1634 	 * @since 2.5.0
   1635 	 *
   1636 	 * @param string $attributes The comments link attributes. Default empty.
   1637 	 */
   1638 	echo apply_filters( 'comments_popup_link_attributes', $attributes );
   1639 
   1640 	echo '>';
   1641 	comments_number( $zero, $one, $more );
   1642 	echo '</a>';
   1643 }
   1644 
   1645 /**
   1646  * Retrieves HTML content for reply to comment link.
   1647  *
   1648  * @since 2.7.0
   1649  * @since 4.4.0 Added the ability for `$comment` to also accept a WP_Comment object.
   1650  *
   1651  * @param array          $args {
   1652  *     Optional. Override default arguments.
   1653  *
   1654  *     @type string $add_below  The first part of the selector used to identify the comment to respond below.
   1655  *                              The resulting value is passed as the first parameter to addComment.moveForm(),
   1656  *                              concatenated as $add_below-$comment->comment_ID. Default 'comment'.
   1657  *     @type string $respond_id The selector identifying the responding comment. Passed as the third parameter
   1658  *                              to addComment.moveForm(), and appended to the link URL as a hash value.
   1659  *                              Default 'respond'.
   1660  *     @type string $reply_text The text of the Reply link. Default 'Reply'.
   1661  *     @type string $login_text The text of the link to reply if logged out. Default 'Log in to Reply'.
   1662  *     @type int    $max_depth  The max depth of the comment tree. Default 0.
   1663  *     @type int    $depth      The depth of the new comment. Must be greater than 0 and less than the value
   1664  *                              of the 'thread_comments_depth' option set in Settings > Discussion. Default 0.
   1665  *     @type string $before     The text or HTML to add before the reply link. Default empty.
   1666  *     @type string $after      The text or HTML to add after the reply link. Default empty.
   1667  * }
   1668  * @param int|WP_Comment $comment Comment being replied to. Default current comment.
   1669  * @param int|WP_Post    $post    Post ID or WP_Post object the comment is going to be displayed on.
   1670  *                                Default current post.
   1671  * @return string|false|null Link to show comment form, if successful. False, if comments are closed.
   1672  */
   1673 function get_comment_reply_link( $args = array(), $comment = null, $post = null ) {
   1674 	$defaults = array(
   1675 		'add_below'     => 'comment',
   1676 		'respond_id'    => 'respond',
   1677 		'reply_text'    => __( 'Reply' ),
   1678 		/* translators: Comment reply button text. %s: Comment author name. */
   1679 		'reply_to_text' => __( 'Reply to %s' ),
   1680 		'login_text'    => __( 'Log in to Reply' ),
   1681 		'max_depth'     => 0,
   1682 		'depth'         => 0,
   1683 		'before'        => '',
   1684 		'after'         => '',
   1685 	);
   1686 
   1687 	$args = wp_parse_args( $args, $defaults );
   1688 
   1689 	if ( 0 == $args['depth'] || $args['max_depth'] <= $args['depth'] ) {
   1690 		return;
   1691 	}
   1692 
   1693 	$comment = get_comment( $comment );
   1694 
   1695 	if ( empty( $comment ) ) {
   1696 		return;
   1697 	}
   1698 
   1699 	if ( empty( $post ) ) {
   1700 		$post = $comment->comment_post_ID;
   1701 	}
   1702 
   1703 	$post = get_post( $post );
   1704 
   1705 	if ( ! comments_open( $post->ID ) ) {
   1706 		return false;
   1707 	}
   1708 
   1709 	if ( get_option( 'page_comments' ) ) {
   1710 		$permalink = str_replace( '#comment-' . $comment->comment_ID, '', get_comment_link( $comment ) );
   1711 	} else {
   1712 		$permalink = get_permalink( $post->ID );
   1713 	}
   1714 
   1715 	/**
   1716 	 * Filters the comment reply link arguments.
   1717 	 *
   1718 	 * @since 4.1.0
   1719 	 *
   1720 	 * @param array      $args    Comment reply link arguments. See get_comment_reply_link()
   1721 	 *                            for more information on accepted arguments.
   1722 	 * @param WP_Comment $comment The object of the comment being replied to.
   1723 	 * @param WP_Post    $post    The WP_Post object.
   1724 	 */
   1725 	$args = apply_filters( 'comment_reply_link_args', $args, $comment, $post );
   1726 
   1727 	if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
   1728 		$link = sprintf(
   1729 			'<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
   1730 			esc_url( wp_login_url( get_permalink() ) ),
   1731 			$args['login_text']
   1732 		);
   1733 	} else {
   1734 		$data_attributes = array(
   1735 			'commentid'      => $comment->comment_ID,
   1736 			'postid'         => $post->ID,
   1737 			'belowelement'   => $args['add_below'] . '-' . $comment->comment_ID,
   1738 			'respondelement' => $args['respond_id'],
   1739 			'replyto'        => sprintf( $args['reply_to_text'], $comment->comment_author ),
   1740 		);
   1741 
   1742 		$data_attribute_string = '';
   1743 
   1744 		foreach ( $data_attributes as $name => $value ) {
   1745 			$data_attribute_string .= " data-${name}=\"" . esc_attr( $value ) . '"';
   1746 		}
   1747 
   1748 		$data_attribute_string = trim( $data_attribute_string );
   1749 
   1750 		$link = sprintf(
   1751 			"<a rel='nofollow' class='comment-reply-link' href='%s' %s aria-label='%s'>%s</a>",
   1752 			esc_url(
   1753 				add_query_arg(
   1754 					array(
   1755 						'replytocom'      => $comment->comment_ID,
   1756 						'unapproved'      => false,
   1757 						'moderation-hash' => false,
   1758 					),
   1759 					$permalink
   1760 				)
   1761 			) . '#' . $args['respond_id'],
   1762 			$data_attribute_string,
   1763 			esc_attr( sprintf( $args['reply_to_text'], $comment->comment_author ) ),
   1764 			$args['reply_text']
   1765 		);
   1766 	}
   1767 
   1768 	/**
   1769 	 * Filters the comment reply link.
   1770 	 *
   1771 	 * @since 2.7.0
   1772 	 *
   1773 	 * @param string     $link    The HTML markup for the comment reply link.
   1774 	 * @param array      $args    An array of arguments overriding the defaults.
   1775 	 * @param WP_Comment $comment The object of the comment being replied.
   1776 	 * @param WP_Post    $post    The WP_Post object.
   1777 	 */
   1778 	return apply_filters( 'comment_reply_link', $args['before'] . $link . $args['after'], $args, $comment, $post );
   1779 }
   1780 
   1781 /**
   1782  * Displays the HTML content for reply to comment link.
   1783  *
   1784  * @since 2.7.0
   1785  *
   1786  * @see get_comment_reply_link()
   1787  *
   1788  * @param array          $args    Optional. Override default options. Default empty array.
   1789  * @param int|WP_Comment $comment Comment being replied to. Default current comment.
   1790  * @param int|WP_Post    $post    Post ID or WP_Post object the comment is going to be displayed on.
   1791  *                                Default current post.
   1792  */
   1793 function comment_reply_link( $args = array(), $comment = null, $post = null ) {
   1794 	echo get_comment_reply_link( $args, $comment, $post );
   1795 }
   1796 
   1797 /**
   1798  * Retrieves HTML content for reply to post link.
   1799  *
   1800  * @since 2.7.0
   1801  *
   1802  * @param array       $args {
   1803  *     Optional. Override default arguments.
   1804  *
   1805  *     @type string $add_below  The first part of the selector used to identify the comment to respond below.
   1806  *                              The resulting value is passed as the first parameter to addComment.moveForm(),
   1807  *                              concatenated as $add_below-$comment->comment_ID. Default is 'post'.
   1808  *     @type string $respond_id The selector identifying the responding comment. Passed as the third parameter
   1809  *                              to addComment.moveForm(), and appended to the link URL as a hash value.
   1810  *                              Default 'respond'.
   1811  *     @type string $reply_text Text of the Reply link. Default is 'Leave a Comment'.
   1812  *     @type string $login_text Text of the link to reply if logged out. Default is 'Log in to leave a Comment'.
   1813  *     @type string $before     Text or HTML to add before the reply link. Default empty.
   1814  *     @type string $after      Text or HTML to add after the reply link. Default empty.
   1815  * }
   1816  * @param int|WP_Post $post    Optional. Post ID or WP_Post object the comment is going to be displayed on.
   1817  *                             Default current post.
   1818  * @return string|false|null Link to show comment form, if successful. False, if comments are closed.
   1819  */
   1820 function get_post_reply_link( $args = array(), $post = null ) {
   1821 	$defaults = array(
   1822 		'add_below'  => 'post',
   1823 		'respond_id' => 'respond',
   1824 		'reply_text' => __( 'Leave a Comment' ),
   1825 		'login_text' => __( 'Log in to leave a Comment' ),
   1826 		'before'     => '',
   1827 		'after'      => '',
   1828 	);
   1829 
   1830 	$args = wp_parse_args( $args, $defaults );
   1831 
   1832 	$post = get_post( $post );
   1833 
   1834 	if ( ! comments_open( $post->ID ) ) {
   1835 		return false;
   1836 	}
   1837 
   1838 	if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
   1839 		$link = sprintf(
   1840 			'<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
   1841 			wp_login_url( get_permalink() ),
   1842 			$args['login_text']
   1843 		);
   1844 	} else {
   1845 		$onclick = sprintf(
   1846 			'return addComment.moveForm( "%1$s-%2$s", "0", "%3$s", "%2$s" )',
   1847 			$args['add_below'],
   1848 			$post->ID,
   1849 			$args['respond_id']
   1850 		);
   1851 
   1852 		$link = sprintf(
   1853 			"<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s'>%s</a>",
   1854 			get_permalink( $post->ID ) . '#' . $args['respond_id'],
   1855 			$onclick,
   1856 			$args['reply_text']
   1857 		);
   1858 	}
   1859 	$formatted_link = $args['before'] . $link . $args['after'];
   1860 
   1861 	/**
   1862 	 * Filters the formatted post comments link HTML.
   1863 	 *
   1864 	 * @since 2.7.0
   1865 	 *
   1866 	 * @param string      $formatted The HTML-formatted post comments link.
   1867 	 * @param int|WP_Post $post      The post ID or WP_Post object.
   1868 	 */
   1869 	return apply_filters( 'post_comments_link', $formatted_link, $post );
   1870 }
   1871 
   1872 /**
   1873  * Displays the HTML content for reply to post link.
   1874  *
   1875  * @since 2.7.0
   1876  *
   1877  * @see get_post_reply_link()
   1878  *
   1879  * @param array       $args Optional. Override default options. Default empty array.
   1880  * @param int|WP_Post $post Post ID or WP_Post object the comment is going to be displayed on.
   1881  *                          Default current post.
   1882  */
   1883 function post_reply_link( $args = array(), $post = null ) {
   1884 	echo get_post_reply_link( $args, $post );
   1885 }
   1886 
   1887 /**
   1888  * Retrieves HTML content for cancel comment reply link.
   1889  *
   1890  * @since 2.7.0
   1891  *
   1892  * @param string $text Optional. Text to display for cancel reply link. If empty,
   1893  *                     defaults to 'Click here to cancel reply'. Default empty.
   1894  * @return string
   1895  */
   1896 function get_cancel_comment_reply_link( $text = '' ) {
   1897 	if ( empty( $text ) ) {
   1898 		$text = __( 'Click here to cancel reply.' );
   1899 	}
   1900 
   1901 	$style = isset( $_GET['replytocom'] ) ? '' : ' style="display:none;"';
   1902 	$link  = esc_html( remove_query_arg( array( 'replytocom', 'unapproved', 'moderation-hash' ) ) ) . '#respond';
   1903 
   1904 	$formatted_link = '<a rel="nofollow" id="cancel-comment-reply-link" href="' . $link . '"' . $style . '>' . $text . '</a>';
   1905 
   1906 	/**
   1907 	 * Filters the cancel comment reply link HTML.
   1908 	 *
   1909 	 * @since 2.7.0
   1910 	 *
   1911 	 * @param string $formatted_link The HTML-formatted cancel comment reply link.
   1912 	 * @param string $link           Cancel comment reply link URL.
   1913 	 * @param string $text           Cancel comment reply link text.
   1914 	 */
   1915 	return apply_filters( 'cancel_comment_reply_link', $formatted_link, $link, $text );
   1916 }
   1917 
   1918 /**
   1919  * Displays HTML content for cancel comment reply link.
   1920  *
   1921  * @since 2.7.0
   1922  *
   1923  * @param string $text Optional. Text to display for cancel reply link. If empty,
   1924  *                     defaults to 'Click here to cancel reply'. Default empty.
   1925  */
   1926 function cancel_comment_reply_link( $text = '' ) {
   1927 	echo get_cancel_comment_reply_link( $text );
   1928 }
   1929 
   1930 /**
   1931  * Retrieves hidden input HTML for replying to comments.
   1932  *
   1933  * @since 3.0.0
   1934  *
   1935  * @param int $post_id Optional. Post ID. Defaults to the current post ID.
   1936  * @return string Hidden input HTML for replying to comments.
   1937  */
   1938 function get_comment_id_fields( $post_id = 0 ) {
   1939 	if ( empty( $post_id ) ) {
   1940 		$post_id = get_the_ID();
   1941 	}
   1942 
   1943 	$reply_to_id = isset( $_GET['replytocom'] ) ? (int) $_GET['replytocom'] : 0;
   1944 	$result      = "<input type='hidden' name='comment_post_ID' value='$post_id' id='comment_post_ID' />\n";
   1945 	$result     .= "<input type='hidden' name='comment_parent' id='comment_parent' value='$reply_to_id' />\n";
   1946 
   1947 	/**
   1948 	 * Filters the returned comment ID fields.
   1949 	 *
   1950 	 * @since 3.0.0
   1951 	 *
   1952 	 * @param string $result      The HTML-formatted hidden ID field comment elements.
   1953 	 * @param int    $post_id     The post ID.
   1954 	 * @param int    $reply_to_id The ID of the comment being replied to.
   1955 	 */
   1956 	return apply_filters( 'comment_id_fields', $result, $post_id, $reply_to_id );
   1957 }
   1958 
   1959 /**
   1960  * Outputs hidden input HTML for replying to comments.
   1961  *
   1962  * Adds two hidden inputs to the comment form to identify the `comment_post_ID`
   1963  * and `comment_parent` values for threaded comments.
   1964  *
   1965  * This tag must be within the `<form>` section of the `comments.php` template.
   1966  *
   1967  * @since 2.7.0
   1968  *
   1969  * @see get_comment_id_fields()
   1970  *
   1971  * @param int $post_id Optional. Post ID. Defaults to the current post ID.
   1972  */
   1973 function comment_id_fields( $post_id = 0 ) {
   1974 	echo get_comment_id_fields( $post_id );
   1975 }
   1976 
   1977 /**
   1978  * Displays text based on comment reply status.
   1979  *
   1980  * Only affects users with JavaScript disabled.
   1981  *
   1982  * @internal The $comment global must be present to allow template tags access to the current
   1983  *           comment. See https://core.trac.wordpress.org/changeset/36512.
   1984  *
   1985  * @since 2.7.0
   1986  *
   1987  * @global WP_Comment $comment Global comment object.
   1988  *
   1989  * @param string|false $no_reply_text  Optional. Text to display when not replying to a comment.
   1990  *                                     Default false.
   1991  * @param string|false $reply_text     Optional. Text to display when replying to a comment.
   1992  *                                     Default false. Accepts "%s" for the author of the comment
   1993  *                                     being replied to.
   1994  * @param bool         $link_to_parent Optional. Boolean to control making the author's name a link
   1995  *                                     to their comment. Default true.
   1996  */
   1997 function comment_form_title( $no_reply_text = false, $reply_text = false, $link_to_parent = true ) {
   1998 	global $comment;
   1999 
   2000 	if ( false === $no_reply_text ) {
   2001 		$no_reply_text = __( 'Leave a Reply' );
   2002 	}
   2003 
   2004 	if ( false === $reply_text ) {
   2005 		/* translators: %s: Author of the comment being replied to. */
   2006 		$reply_text = __( 'Leave a Reply to %s' );
   2007 	}
   2008 
   2009 	$reply_to_id = isset( $_GET['replytocom'] ) ? (int) $_GET['replytocom'] : 0;
   2010 
   2011 	if ( 0 == $reply_to_id ) {
   2012 		echo $no_reply_text;
   2013 	} else {
   2014 		// Sets the global so that template tags can be used in the comment form.
   2015 		$comment = get_comment( $reply_to_id );
   2016 
   2017 		if ( $link_to_parent ) {
   2018 			$author = '<a href="#comment-' . get_comment_ID() . '">' . get_comment_author( $comment ) . '</a>';
   2019 		} else {
   2020 			$author = get_comment_author( $comment );
   2021 		}
   2022 
   2023 		printf( $reply_text, $author );
   2024 	}
   2025 }
   2026 
   2027 /**
   2028  * Displays a list of comments.
   2029  *
   2030  * Used in the comments.php template to list comments for a particular post.
   2031  *
   2032  * @since 2.7.0
   2033  *
   2034  * @see WP_Query->comments
   2035  *
   2036  * @global WP_Query $wp_query           WordPress Query object.
   2037  * @global int      $comment_alt
   2038  * @global int      $comment_depth
   2039  * @global int      $comment_thread_alt
   2040  * @global bool     $overridden_cpage
   2041  * @global bool     $in_comment_loop
   2042  *
   2043  * @param string|array $args {
   2044  *     Optional. Formatting options.
   2045  *
   2046  *     @type object   $walker            Instance of a Walker class to list comments. Default null.
   2047  *     @type int      $max_depth         The maximum comments depth. Default empty.
   2048  *     @type string   $style             The style of list ordering. Accepts 'ul', 'ol', or 'div'.
   2049  *                                       'div' will result in no additional list markup. Default 'ul'.
   2050  *     @type callable $callback          Callback function to use. Default null.
   2051  *     @type callable $end-callback      Callback function to use at the end. Default null.
   2052  *     @type string   $type              Type of comments to list. Accepts 'all', 'comment',
   2053  *                                       'pingback', 'trackback', 'pings'. Default 'all'.
   2054  *     @type int      $page              Page ID to list comments for. Default empty.
   2055  *     @type int      $per_page          Number of comments to list per page. Default empty.
   2056  *     @type int      $avatar_size       Height and width dimensions of the avatar size. Default 32.
   2057  *     @type bool     $reverse_top_level Ordering of the listed comments. If true, will display
   2058  *                                       newest comments first. Default null.
   2059  *     @type bool     $reverse_children  Whether to reverse child comments in the list. Default null.
   2060  *     @type string   $format            How to format the comments list. Accepts 'html5', 'xhtml'.
   2061  *                                       Default 'html5' if the theme supports it.
   2062  *     @type bool     $short_ping        Whether to output short pings. Default false.
   2063  *     @type bool     $echo              Whether to echo the output or return it. Default true.
   2064  * }
   2065  * @param WP_Comment[] $comments Optional. Array of WP_Comment objects.
   2066  * @return void|string Void if 'echo' argument is true, or no comments to list.
   2067  *                     Otherwise, HTML list of comments.
   2068  */
   2069 function wp_list_comments( $args = array(), $comments = null ) {
   2070 	global $wp_query, $comment_alt, $comment_depth, $comment_thread_alt, $overridden_cpage, $in_comment_loop;
   2071 
   2072 	$in_comment_loop = true;
   2073 
   2074 	$comment_alt        = 0;
   2075 	$comment_thread_alt = 0;
   2076 	$comment_depth      = 1;
   2077 
   2078 	$defaults = array(
   2079 		'walker'            => null,
   2080 		'max_depth'         => '',
   2081 		'style'             => 'ul',
   2082 		'callback'          => null,
   2083 		'end-callback'      => null,
   2084 		'type'              => 'all',
   2085 		'page'              => '',
   2086 		'per_page'          => '',
   2087 		'avatar_size'       => 32,
   2088 		'reverse_top_level' => null,
   2089 		'reverse_children'  => '',
   2090 		'format'            => current_theme_supports( 'html5', 'comment-list' ) ? 'html5' : 'xhtml',
   2091 		'short_ping'        => false,
   2092 		'echo'              => true,
   2093 	);
   2094 
   2095 	$parsed_args = wp_parse_args( $args, $defaults );
   2096 
   2097 	/**
   2098 	 * Filters the arguments used in retrieving the comment list.
   2099 	 *
   2100 	 * @since 4.0.0
   2101 	 *
   2102 	 * @see wp_list_comments()
   2103 	 *
   2104 	 * @param array $parsed_args An array of arguments for displaying comments.
   2105 	 */
   2106 	$parsed_args = apply_filters( 'wp_list_comments_args', $parsed_args );
   2107 
   2108 	// Figure out what comments we'll be looping through ($_comments).
   2109 	if ( null !== $comments ) {
   2110 		$comments = (array) $comments;
   2111 		if ( empty( $comments ) ) {
   2112 			return;
   2113 		}
   2114 		if ( 'all' !== $parsed_args['type'] ) {
   2115 			$comments_by_type = separate_comments( $comments );
   2116 			if ( empty( $comments_by_type[ $parsed_args['type'] ] ) ) {
   2117 				return;
   2118 			}
   2119 			$_comments = $comments_by_type[ $parsed_args['type'] ];
   2120 		} else {
   2121 			$_comments = $comments;
   2122 		}
   2123 	} else {
   2124 		/*
   2125 		 * If 'page' or 'per_page' has been passed, and does not match what's in $wp_query,
   2126 		 * perform a separate comment query and allow Walker_Comment to paginate.
   2127 		 */
   2128 		if ( $parsed_args['page'] || $parsed_args['per_page'] ) {
   2129 			$current_cpage = get_query_var( 'cpage' );
   2130 			if ( ! $current_cpage ) {
   2131 				$current_cpage = 'newest' === get_option( 'default_comments_page' ) ? 1 : $wp_query->max_num_comment_pages;
   2132 			}
   2133 
   2134 			$current_per_page = get_query_var( 'comments_per_page' );
   2135 			if ( $parsed_args['page'] != $current_cpage || $parsed_args['per_page'] != $current_per_page ) {
   2136 				$comment_args = array(
   2137 					'post_id' => get_the_ID(),
   2138 					'orderby' => 'comment_date_gmt',
   2139 					'order'   => 'ASC',
   2140 					'status'  => 'approve',
   2141 				);
   2142 
   2143 				if ( is_user_logged_in() ) {
   2144 					$comment_args['include_unapproved'] = array( get_current_user_id() );
   2145 				} else {
   2146 					$unapproved_email = wp_get_unapproved_comment_author_email();
   2147 
   2148 					if ( $unapproved_email ) {
   2149 						$comment_args['include_unapproved'] = array( $unapproved_email );
   2150 					}
   2151 				}
   2152 
   2153 				$comments = get_comments( $comment_args );
   2154 
   2155 				if ( 'all' !== $parsed_args['type'] ) {
   2156 					$comments_by_type = separate_comments( $comments );
   2157 					if ( empty( $comments_by_type[ $parsed_args['type'] ] ) ) {
   2158 						return;
   2159 					}
   2160 
   2161 					$_comments = $comments_by_type[ $parsed_args['type'] ];
   2162 				} else {
   2163 					$_comments = $comments;
   2164 				}
   2165 			}
   2166 
   2167 			// Otherwise, fall back on the comments from `$wp_query->comments`.
   2168 		} else {
   2169 			if ( empty( $wp_query->comments ) ) {
   2170 				return;
   2171 			}
   2172 			if ( 'all' !== $parsed_args['type'] ) {
   2173 				if ( empty( $wp_query->comments_by_type ) ) {
   2174 					$wp_query->comments_by_type = separate_comments( $wp_query->comments );
   2175 				}
   2176 				if ( empty( $wp_query->comments_by_type[ $parsed_args['type'] ] ) ) {
   2177 					return;
   2178 				}
   2179 				$_comments = $wp_query->comments_by_type[ $parsed_args['type'] ];
   2180 			} else {
   2181 				$_comments = $wp_query->comments;
   2182 			}
   2183 
   2184 			if ( $wp_query->max_num_comment_pages ) {
   2185 				$default_comments_page = get_option( 'default_comments_page' );
   2186 				$cpage                 = get_query_var( 'cpage' );
   2187 				if ( 'newest' === $default_comments_page ) {
   2188 					$parsed_args['cpage'] = $cpage;
   2189 
   2190 					/*
   2191 					* When first page shows oldest comments, post permalink is the same as
   2192 					* the comment permalink.
   2193 					*/
   2194 				} elseif ( 1 == $cpage ) {
   2195 					$parsed_args['cpage'] = '';
   2196 				} else {
   2197 					$parsed_args['cpage'] = $cpage;
   2198 				}
   2199 
   2200 				$parsed_args['page']     = 0;
   2201 				$parsed_args['per_page'] = 0;
   2202 			}
   2203 		}
   2204 	}
   2205 
   2206 	if ( '' === $parsed_args['per_page'] && get_option( 'page_comments' ) ) {
   2207 		$parsed_args['per_page'] = get_query_var( 'comments_per_page' );
   2208 	}
   2209 
   2210 	if ( empty( $parsed_args['per_page'] ) ) {
   2211 		$parsed_args['per_page'] = 0;
   2212 		$parsed_args['page']     = 0;
   2213 	}
   2214 
   2215 	if ( '' === $parsed_args['max_depth'] ) {
   2216 		if ( get_option( 'thread_comments' ) ) {
   2217 			$parsed_args['max_depth'] = get_option( 'thread_comments_depth' );
   2218 		} else {
   2219 			$parsed_args['max_depth'] = -1;
   2220 		}
   2221 	}
   2222 
   2223 	if ( '' === $parsed_args['page'] ) {
   2224 		if ( empty( $overridden_cpage ) ) {
   2225 			$parsed_args['page'] = get_query_var( 'cpage' );
   2226 		} else {
   2227 			$threaded            = ( -1 != $parsed_args['max_depth'] );
   2228 			$parsed_args['page'] = ( 'newest' === get_option( 'default_comments_page' ) ) ? get_comment_pages_count( $_comments, $parsed_args['per_page'], $threaded ) : 1;
   2229 			set_query_var( 'cpage', $parsed_args['page'] );
   2230 		}
   2231 	}
   2232 	// Validation check.
   2233 	$parsed_args['page'] = (int) $parsed_args['page'];
   2234 	if ( 0 == $parsed_args['page'] && 0 != $parsed_args['per_page'] ) {
   2235 		$parsed_args['page'] = 1;
   2236 	}
   2237 
   2238 	if ( null === $parsed_args['reverse_top_level'] ) {
   2239 		$parsed_args['reverse_top_level'] = ( 'desc' === get_option( 'comment_order' ) );
   2240 	}
   2241 
   2242 	wp_queue_comments_for_comment_meta_lazyload( $_comments );
   2243 
   2244 	if ( empty( $parsed_args['walker'] ) ) {
   2245 		$walker = new Walker_Comment;
   2246 	} else {
   2247 		$walker = $parsed_args['walker'];
   2248 	}
   2249 
   2250 	$output = $walker->paged_walk( $_comments, $parsed_args['max_depth'], $parsed_args['page'], $parsed_args['per_page'], $parsed_args );
   2251 
   2252 	$in_comment_loop = false;
   2253 
   2254 	if ( $parsed_args['echo'] ) {
   2255 		echo $output;
   2256 	} else {
   2257 		return $output;
   2258 	}
   2259 }
   2260 
   2261 /**
   2262  * Outputs a complete commenting form for use within a template.
   2263  *
   2264  * Most strings and form fields may be controlled through the `$args` array passed
   2265  * into the function, while you may also choose to use the {@see 'comment_form_default_fields'}
   2266  * filter to modify the array of default fields if you'd just like to add a new
   2267  * one or remove a single field. All fields are also individually passed through
   2268  * a filter of the {@see 'comment_form_field_$name'} where `$name` is the key used
   2269  * in the array of fields.
   2270  *
   2271  * @since 3.0.0
   2272  * @since 4.1.0 Introduced the 'class_submit' argument.
   2273  * @since 4.2.0 Introduced the 'submit_button' and 'submit_fields' arguments.
   2274  * @since 4.4.0 Introduced the 'class_form', 'title_reply_before', 'title_reply_after',
   2275  *              'cancel_reply_before', and 'cancel_reply_after' arguments.
   2276  * @since 4.5.0 The 'author', 'email', and 'url' form fields are limited to 245, 100,
   2277  *              and 200 characters, respectively.
   2278  * @since 4.6.0 Introduced the 'action' argument.
   2279  * @since 4.9.6 Introduced the 'cookies' default comment field.
   2280  * @since 5.5.0 Introduced the 'class_container' argument.
   2281  *
   2282  * @param array       $args {
   2283  *     Optional. Default arguments and form fields to override.
   2284  *
   2285  *     @type array $fields {
   2286  *         Default comment fields, filterable by default via the {@see 'comment_form_default_fields'} hook.
   2287  *
   2288  *         @type string $author  Comment author field HTML.
   2289  *         @type string $email   Comment author email field HTML.
   2290  *         @type string $url     Comment author URL field HTML.
   2291  *         @type string $cookies Comment cookie opt-in field HTML.
   2292  *     }
   2293  *     @type string $comment_field        The comment textarea field HTML.
   2294  *     @type string $must_log_in          HTML element for a 'must be logged in to comment' message.
   2295  *     @type string $logged_in_as         HTML element for a 'logged in as [user]' message.
   2296  *     @type string $comment_notes_before HTML element for a message displayed before the comment fields
   2297  *                                        if the user is not logged in.
   2298  *                                        Default 'Your email address will not be published.'.
   2299  *     @type string $comment_notes_after  HTML element for a message displayed after the textarea field.
   2300  *     @type string $action               The comment form element action attribute. Default '/wp-comments-post.php'.
   2301  *     @type string $id_form              The comment form element id attribute. Default 'commentform'.
   2302  *     @type string $id_submit            The comment submit element id attribute. Default 'submit'.
   2303  *     @type string $class_container      The comment form container class attribute. Default 'comment-respond'.
   2304  *     @type string $class_form           The comment form element class attribute. Default 'comment-form'.
   2305  *     @type string $class_submit         The comment submit element class attribute. Default 'submit'.
   2306  *     @type string $name_submit          The comment submit element name attribute. Default 'submit'.
   2307  *     @type string $title_reply          The translatable 'reply' button label. Default 'Leave a Reply'.
   2308  *     @type string $title_reply_to       The translatable 'reply-to' button label. Default 'Leave a Reply to %s',
   2309  *                                        where %s is the author of the comment being replied to.
   2310  *     @type string $title_reply_before   HTML displayed before the comment form title.
   2311  *                                        Default: '<h3 id="reply-title" class="comment-reply-title">'.
   2312  *     @type string $title_reply_after    HTML displayed after the comment form title.
   2313  *                                        Default: '</h3>'.
   2314  *     @type string $cancel_reply_before  HTML displayed before the cancel reply link.
   2315  *     @type string $cancel_reply_after   HTML displayed after the cancel reply link.
   2316  *     @type string $cancel_reply_link    The translatable 'cancel reply' button label. Default 'Cancel reply'.
   2317  *     @type string $label_submit         The translatable 'submit' button label. Default 'Post a comment'.
   2318  *     @type string $submit_button        HTML format for the Submit button.
   2319  *                                        Default: '<input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" />'.
   2320  *     @type string $submit_field         HTML format for the markup surrounding the Submit button and comment hidden
   2321  *                                        fields. Default: '<p class="form-submit">%1$s %2$s</p>', where %1$s is the
   2322  *                                        submit button markup and %2$s is the comment hidden fields.
   2323  *     @type string $format               The comment form format. Default 'xhtml'. Accepts 'xhtml', 'html5'.
   2324  * }
   2325  * @param int|WP_Post $post_id Post ID or WP_Post object to generate the form for. Default current post.
   2326  */
   2327 function comment_form( $args = array(), $post_id = null ) {
   2328 	if ( null === $post_id ) {
   2329 		$post_id = get_the_ID();
   2330 	}
   2331 
   2332 	// Exit the function when comments for the post are closed.
   2333 	if ( ! comments_open( $post_id ) ) {
   2334 		/**
   2335 		 * Fires after the comment form if comments are closed.
   2336 		 *
   2337 		 * @since 3.0.0
   2338 		 */
   2339 		do_action( 'comment_form_comments_closed' );
   2340 
   2341 		return;
   2342 	}
   2343 
   2344 	$commenter     = wp_get_current_commenter();
   2345 	$user          = wp_get_current_user();
   2346 	$user_identity = $user->exists() ? $user->display_name : '';
   2347 
   2348 	$args = wp_parse_args( $args );
   2349 	if ( ! isset( $args['format'] ) ) {
   2350 		$args['format'] = current_theme_supports( 'html5', 'comment-form' ) ? 'html5' : 'xhtml';
   2351 	}
   2352 
   2353 	$req      = get_option( 'require_name_email' );
   2354 	$html_req = ( $req ? " required='required'" : '' );
   2355 	$html5    = 'html5' === $args['format'];
   2356 
   2357 	$fields = array(
   2358 		'author' => sprintf(
   2359 			'<p class="comment-form-author">%s %s</p>',
   2360 			sprintf(
   2361 				'<label for="author">%s%s</label>',
   2362 				__( 'Name' ),
   2363 				( $req ? ' <span class="required">*</span>' : '' )
   2364 			),
   2365 			sprintf(
   2366 				'<input id="author" name="author" type="text" value="%s" size="30" maxlength="245"%s />',
   2367 				esc_attr( $commenter['comment_author'] ),
   2368 				$html_req
   2369 			)
   2370 		),
   2371 		'email'  => sprintf(
   2372 			'<p class="comment-form-email">%s %s</p>',
   2373 			sprintf(
   2374 				'<label for="email">%s%s</label>',
   2375 				__( 'Email' ),
   2376 				( $req ? ' <span class="required">*</span>' : '' )
   2377 			),
   2378 			sprintf(
   2379 				'<input id="email" name="email" %s value="%s" size="30" maxlength="100" aria-describedby="email-notes"%s />',
   2380 				( $html5 ? 'type="email"' : 'type="text"' ),
   2381 				esc_attr( $commenter['comment_author_email'] ),
   2382 				$html_req
   2383 			)
   2384 		),
   2385 		'url'    => sprintf(
   2386 			'<p class="comment-form-url">%s %s</p>',
   2387 			sprintf(
   2388 				'<label for="url">%s</label>',
   2389 				__( 'Website' )
   2390 			),
   2391 			sprintf(
   2392 				'<input id="url" name="url" %s value="%s" size="30" maxlength="200" />',
   2393 				( $html5 ? 'type="url"' : 'type="text"' ),
   2394 				esc_attr( $commenter['comment_author_url'] )
   2395 			)
   2396 		),
   2397 	);
   2398 
   2399 	if ( has_action( 'set_comment_cookies', 'wp_set_comment_cookies' ) && get_option( 'show_comments_cookies_opt_in' ) ) {
   2400 		$consent = empty( $commenter['comment_author_email'] ) ? '' : ' checked="checked"';
   2401 
   2402 		$fields['cookies'] = sprintf(
   2403 			'<p class="comment-form-cookies-consent">%s %s</p>',
   2404 			sprintf(
   2405 				'<input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"%s />',
   2406 				$consent
   2407 			),
   2408 			sprintf(
   2409 				'<label for="wp-comment-cookies-consent">%s</label>',
   2410 				__( 'Save my name, email, and website in this browser for the next time I comment.' )
   2411 			)
   2412 		);
   2413 
   2414 		// Ensure that the passed fields include cookies consent.
   2415 		if ( isset( $args['fields'] ) && ! isset( $args['fields']['cookies'] ) ) {
   2416 			$args['fields']['cookies'] = $fields['cookies'];
   2417 		}
   2418 	}
   2419 
   2420 	$required_text = sprintf(
   2421 		/* translators: %s: Asterisk symbol (*). */
   2422 		' ' . __( 'Required fields are marked %s' ),
   2423 		'<span class="required">*</span>'
   2424 	);
   2425 
   2426 	/**
   2427 	 * Filters the default comment form fields.
   2428 	 *
   2429 	 * @since 3.0.0
   2430 	 *
   2431 	 * @param string[] $fields Array of the default comment fields.
   2432 	 */
   2433 	$fields = apply_filters( 'comment_form_default_fields', $fields );
   2434 
   2435 	$defaults = array(
   2436 		'fields'               => $fields,
   2437 		'comment_field'        => sprintf(
   2438 			'<p class="comment-form-comment">%s %s</p>',
   2439 			sprintf(
   2440 				'<label for="comment">%s</label>',
   2441 				_x( 'Comment', 'noun' )
   2442 			),
   2443 			'<textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" required="required"></textarea>'
   2444 		),
   2445 		'must_log_in'          => sprintf(
   2446 			'<p class="must-log-in">%s</p>',
   2447 			sprintf(
   2448 				/* translators: %s: Login URL. */
   2449 				__( 'You must be <a href="%s">logged in</a> to post a comment.' ),
   2450 				/** This filter is documented in wp-includes/link-template.php */
   2451 				wp_login_url( apply_filters( 'the_permalink', get_permalink( $post_id ), $post_id ) )
   2452 			)
   2453 		),
   2454 		'logged_in_as'         => sprintf(
   2455 			'<p class="logged-in-as">%s</p>',
   2456 			sprintf(
   2457 				/* translators: 1: Edit user link, 2: Accessibility text, 3: User name, 4: Logout URL. */
   2458 				__( '<a href="%1$s" aria-label="%2$s">Logged in as %3$s</a>. <a href="%4$s">Log out?</a>' ),
   2459 				get_edit_user_link(),
   2460 				/* translators: %s: User name. */
   2461 				esc_attr( sprintf( __( 'Logged in as %s. Edit your profile.' ), $user_identity ) ),
   2462 				$user_identity,
   2463 				/** This filter is documented in wp-includes/link-template.php */
   2464 				wp_logout_url( apply_filters( 'the_permalink', get_permalink( $post_id ), $post_id ) )
   2465 			)
   2466 		),
   2467 		'comment_notes_before' => sprintf(
   2468 			'<p class="comment-notes">%s%s</p>',
   2469 			sprintf(
   2470 				'<span id="email-notes">%s</span>',
   2471 				__( 'Your email address will not be published.' )
   2472 			),
   2473 			( $req ? $required_text : '' )
   2474 		),
   2475 		'comment_notes_after'  => '',
   2476 		'action'               => site_url( '/wp-comments-post.php' ),
   2477 		'id_form'              => 'commentform',
   2478 		'id_submit'            => 'submit',
   2479 		'class_container'      => 'comment-respond',
   2480 		'class_form'           => 'comment-form',
   2481 		'class_submit'         => 'submit',
   2482 		'name_submit'          => 'submit',
   2483 		'title_reply'          => __( 'Leave a Reply' ),
   2484 		/* translators: %s: Author of the comment being replied to. */
   2485 		'title_reply_to'       => __( 'Leave a Reply to %s' ),
   2486 		'title_reply_before'   => '<h3 id="reply-title" class="comment-reply-title">',
   2487 		'title_reply_after'    => '</h3>',
   2488 		'cancel_reply_before'  => ' <small>',
   2489 		'cancel_reply_after'   => '</small>',
   2490 		'cancel_reply_link'    => __( 'Cancel reply' ),
   2491 		'label_submit'         => __( 'Post Comment' ),
   2492 		'submit_button'        => '<input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" />',
   2493 		'submit_field'         => '<p class="form-submit">%1$s %2$s</p>',
   2494 		'format'               => 'xhtml',
   2495 	);
   2496 
   2497 	/**
   2498 	 * Filters the comment form default arguments.
   2499 	 *
   2500 	 * Use {@see 'comment_form_default_fields'} to filter the comment fields.
   2501 	 *
   2502 	 * @since 3.0.0
   2503 	 *
   2504 	 * @param array $defaults The default comment form arguments.
   2505 	 */
   2506 	$args = wp_parse_args( $args, apply_filters( 'comment_form_defaults', $defaults ) );
   2507 
   2508 	// Ensure that the filtered arguments contain all required default values.
   2509 	$args = array_merge( $defaults, $args );
   2510 
   2511 	// Remove `aria-describedby` from the email field if there's no associated description.
   2512 	if ( isset( $args['fields']['email'] ) && false === strpos( $args['comment_notes_before'], 'id="email-notes"' ) ) {
   2513 		$args['fields']['email'] = str_replace(
   2514 			' aria-describedby="email-notes"',
   2515 			'',
   2516 			$args['fields']['email']
   2517 		);
   2518 	}
   2519 
   2520 	/**
   2521 	 * Fires before the comment form.
   2522 	 *
   2523 	 * @since 3.0.0
   2524 	 */
   2525 	do_action( 'comment_form_before' );
   2526 	?>
   2527 	<div id="respond" class="<?php echo esc_attr( $args['class_container'] ); ?>">
   2528 		<?php
   2529 		echo $args['title_reply_before'];
   2530 
   2531 		comment_form_title( $args['title_reply'], $args['title_reply_to'] );
   2532 
   2533 		echo $args['cancel_reply_before'];
   2534 
   2535 		cancel_comment_reply_link( $args['cancel_reply_link'] );
   2536 
   2537 		echo $args['cancel_reply_after'];
   2538 
   2539 		echo $args['title_reply_after'];
   2540 
   2541 		if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) :
   2542 
   2543 			echo $args['must_log_in'];
   2544 			/**
   2545 			 * Fires after the HTML-formatted 'must log in after' message in the comment form.
   2546 			 *
   2547 			 * @since 3.0.0
   2548 			 */
   2549 			do_action( 'comment_form_must_log_in_after' );
   2550 
   2551 		else :
   2552 
   2553 			printf(
   2554 				'<form action="%s" method="post" id="%s" class="%s"%s>',
   2555 				esc_url( $args['action'] ),
   2556 				esc_attr( $args['id_form'] ),
   2557 				esc_attr( $args['class_form'] ),
   2558 				( $html5 ? ' novalidate' : '' )
   2559 			);
   2560 
   2561 			/**
   2562 			 * Fires at the top of the comment form, inside the form tag.
   2563 			 *
   2564 			 * @since 3.0.0
   2565 			 */
   2566 			do_action( 'comment_form_top' );
   2567 
   2568 			if ( is_user_logged_in() ) :
   2569 
   2570 				/**
   2571 				 * Filters the 'logged in' message for the comment form for display.
   2572 				 *
   2573 				 * @since 3.0.0
   2574 				 *
   2575 				 * @param string $args_logged_in The logged-in-as HTML-formatted message.
   2576 				 * @param array  $commenter      An array containing the comment author's
   2577 				 *                               username, email, and URL.
   2578 				 * @param string $user_identity  If the commenter is a registered user,
   2579 				 *                               the display name, blank otherwise.
   2580 				 */
   2581 				echo apply_filters( 'comment_form_logged_in', $args['logged_in_as'], $commenter, $user_identity );
   2582 
   2583 				/**
   2584 				 * Fires after the is_user_logged_in() check in the comment form.
   2585 				 *
   2586 				 * @since 3.0.0
   2587 				 *
   2588 				 * @param array  $commenter     An array containing the comment author's
   2589 				 *                              username, email, and URL.
   2590 				 * @param string $user_identity If the commenter is a registered user,
   2591 				 *                              the display name, blank otherwise.
   2592 				 */
   2593 				do_action( 'comment_form_logged_in_after', $commenter, $user_identity );
   2594 
   2595 			else :
   2596 
   2597 				echo $args['comment_notes_before'];
   2598 
   2599 			endif;
   2600 
   2601 			// Prepare an array of all fields, including the textarea.
   2602 			$comment_fields = array( 'comment' => $args['comment_field'] ) + (array) $args['fields'];
   2603 
   2604 			/**
   2605 			 * Filters the comment form fields, including the textarea.
   2606 			 *
   2607 			 * @since 4.4.0
   2608 			 *
   2609 			 * @param array $comment_fields The comment fields.
   2610 			 */
   2611 			$comment_fields = apply_filters( 'comment_form_fields', $comment_fields );
   2612 
   2613 			// Get an array of field names, excluding the textarea.
   2614 			$comment_field_keys = array_diff( array_keys( $comment_fields ), array( 'comment' ) );
   2615 
   2616 			// Get the first and the last field name, excluding the textarea.
   2617 			$first_field = reset( $comment_field_keys );
   2618 			$last_field  = end( $comment_field_keys );
   2619 
   2620 			foreach ( $comment_fields as $name => $field ) {
   2621 
   2622 				if ( 'comment' === $name ) {
   2623 
   2624 					/**
   2625 					 * Filters the content of the comment textarea field for display.
   2626 					 *
   2627 					 * @since 3.0.0
   2628 					 *
   2629 					 * @param string $args_comment_field The content of the comment textarea field.
   2630 					 */
   2631 					echo apply_filters( 'comment_form_field_comment', $field );
   2632 
   2633 					echo $args['comment_notes_after'];
   2634 
   2635 				} elseif ( ! is_user_logged_in() ) {
   2636 
   2637 					if ( $first_field === $name ) {
   2638 						/**
   2639 						 * Fires before the comment fields in the comment form, excluding the textarea.
   2640 						 *
   2641 						 * @since 3.0.0
   2642 						 */
   2643 						do_action( 'comment_form_before_fields' );
   2644 					}
   2645 
   2646 					/**
   2647 					 * Filters a comment form field for display.
   2648 					 *
   2649 					 * The dynamic portion of the filter hook, `$name`, refers to the name
   2650 					 * of the comment form field. Such as 'author', 'email', or 'url'.
   2651 					 *
   2652 					 * @since 3.0.0
   2653 					 *
   2654 					 * @param string $field The HTML-formatted output of the comment form field.
   2655 					 */
   2656 					echo apply_filters( "comment_form_field_{$name}", $field ) . "\n";
   2657 
   2658 					if ( $last_field === $name ) {
   2659 						/**
   2660 						 * Fires after the comment fields in the comment form, excluding the textarea.
   2661 						 *
   2662 						 * @since 3.0.0
   2663 						 */
   2664 						do_action( 'comment_form_after_fields' );
   2665 					}
   2666 				}
   2667 			}
   2668 
   2669 			$submit_button = sprintf(
   2670 				$args['submit_button'],
   2671 				esc_attr( $args['name_submit'] ),
   2672 				esc_attr( $args['id_submit'] ),
   2673 				esc_attr( $args['class_submit'] ),
   2674 				esc_attr( $args['label_submit'] )
   2675 			);
   2676 
   2677 			/**
   2678 			 * Filters the submit button for the comment form to display.
   2679 			 *
   2680 			 * @since 4.2.0
   2681 			 *
   2682 			 * @param string $submit_button HTML markup for the submit button.
   2683 			 * @param array  $args          Arguments passed to comment_form().
   2684 			 */
   2685 			$submit_button = apply_filters( 'comment_form_submit_button', $submit_button, $args );
   2686 
   2687 			$submit_field = sprintf(
   2688 				$args['submit_field'],
   2689 				$submit_button,
   2690 				get_comment_id_fields( $post_id )
   2691 			);
   2692 
   2693 			/**
   2694 			 * Filters the submit field for the comment form to display.
   2695 			 *
   2696 			 * The submit field includes the submit button, hidden fields for the
   2697 			 * comment form, and any wrapper markup.
   2698 			 *
   2699 			 * @since 4.2.0
   2700 			 *
   2701 			 * @param string $submit_field HTML markup for the submit field.
   2702 			 * @param array  $args         Arguments passed to comment_form().
   2703 			 */
   2704 			echo apply_filters( 'comment_form_submit_field', $submit_field, $args );
   2705 
   2706 			/**
   2707 			 * Fires at the bottom of the comment form, inside the closing form tag.
   2708 			 *
   2709 			 * @since 1.5.0
   2710 			 *
   2711 			 * @param int $post_id The post ID.
   2712 			 */
   2713 			do_action( 'comment_form', $post_id );
   2714 
   2715 			echo '</form>';
   2716 
   2717 		endif;
   2718 		?>
   2719 	</div><!-- #respond -->
   2720 	<?php
   2721 
   2722 	/**
   2723 	 * Fires after the comment form.
   2724 	 *
   2725 	 * @since 3.0.0
   2726 	 */
   2727 	do_action( 'comment_form_after' );
   2728 }