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