Make WordPress Core

Ticket #61715: get_comment_author.patch

File get_comment_author.patch, 102.6 KB (added by iflairwebtechnologies, 11 months ago)

Improve type handling and readability in get_comment_author() function

  • wp-includes/comment-template.php

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