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

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1