Issues (4967)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/wp-includes/comment-template.php (37 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Comment template functions
4
 *
5
 * These functions are meant to live inside of the WordPress loop.
6
 *
7
 * @package WordPress
8
 * @subpackage Template
9
 */
10
11
/**
12
 * Retrieve the author of the current comment.
13
 *
14
 * If the comment has an empty comment_author field, then 'Anonymous' person is
15
 * assumed.
16
 *
17
 * @since 1.5.0
18
 * @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.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
21
 *									 Default current comment.
22
 * @return string The comment author
23
 */
24
function get_comment_author( $comment_ID = 0 ) {
25
	$comment = get_comment( $comment_ID );
26
27
	if ( empty( $comment->comment_author ) ) {
28
		if ( $comment->user_id && $user = get_userdata( $comment->user_id ) )
29
			$author = $user->display_name;
30
		else
31
			$author = __('Anonymous');
32
	} else {
33
		$author = $comment->comment_author;
34
	}
35
36
	/**
37
	 * Filters the returned comment author name.
38
	 *
39
	 * @since 1.5.0
40
	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
41
	 *
42
	 * @param string     $author     The comment author's username.
43
	 * @param int        $comment_ID The comment ID.
44
	 * @param WP_Comment $comment    The comment object.
45
	 */
46
	return apply_filters( 'get_comment_author', $author, $comment->comment_ID, $comment );
47
}
48
49
/**
50
 * Displays the author of the current comment.
51
 *
52
 * @since 0.71
53
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
54
 *
55
 * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to print the author.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
56
 *									 Default current comment.
57
 */
58
function comment_author( $comment_ID = 0 ) {
59
	$comment = get_comment( $comment_ID );
60
	$author  = get_comment_author( $comment );
61
62
	/**
63
	 * Filters the comment author's name for display.
64
	 *
65
	 * @since 1.2.0
66
	 * @since 4.1.0 The `$comment_ID` parameter was added.
67
	 *
68
	 * @param string $author     The comment author's username.
69
	 * @param int    $comment_ID The comment ID.
70
	 */
71
	echo apply_filters( 'comment_author', $author, $comment->comment_ID );
72
}
73
74
/**
75
 * Retrieve the email of the author of the current comment.
76
 *
77
 * @since 1.5.0
78
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
79
 *
80
 * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to get the author's email.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
81
 *									 Default current comment.
82
 * @return string The current comment author's email
83
 */
84 View Code Duplication
function get_comment_author_email( $comment_ID = 0 ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
85
	$comment = get_comment( $comment_ID );
86
87
	/**
88
	 * Filters the comment author's returned email address.
89
	 *
90
	 * @since 1.5.0
91
	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
92
	 *
93
	 * @param string     $comment_author_email The comment author's email address.
94
	 * @param int        $comment_ID           The comment ID.
95
	 * @param WP_Comment $comment              The comment object.
96
	 */
97
	return apply_filters( 'get_comment_author_email', $comment->comment_author_email, $comment->comment_ID, $comment );
98
}
99
100
/**
101
 * Display the email of the author of the current global $comment.
102
 *
103
 * Care should be taken to protect the email address and assure that email
104
 * harvesters do not capture your commentors' email address. Most assume that
105
 * their email address will not appear in raw form on the site. Doing so will
106
 * enable anyone, including those that people don't want to get the email
107
 * address and use it for their own means good and bad.
108
 *
109
 * @since 0.71
110
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
111
 *
112
 * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to print the author's email.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
113
 *									 Default current comment.
114
 */
115 View Code Duplication
function comment_author_email( $comment_ID = 0 ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
116
	$comment      = get_comment( $comment_ID );
117
	$author_email = get_comment_author_email( $comment );
118
119
	/**
120
	 * Filters the comment author's email for display.
121
	 *
122
	 * @since 1.2.0
123
	 * @since 4.1.0 The `$comment_ID` parameter was added.
124
	 *
125
	 * @param string $author_email The comment author's email address.
126
	 * @param int    $comment_ID   The comment ID.
127
	 */
128
	echo apply_filters( 'author_email', $author_email, $comment->comment_ID );
129
}
130
131
/**
132
 * Display the html email link to the author of the current comment.
133
 *
134
 * Care should be taken to protect the email address and assure that email
135
 * harvesters do not capture your commentors' email address. Most assume that
136
 * their email address will not appear in raw form on the site. Doing so will
137
 * enable anyone, including those that people don't want to get the email
138
 * address and use it for their own means good and bad.
139
 *
140
 * @since 0.71
141
 * @since 4.6.0 Added the `$comment` parameter.
142
 *
143
 * @param string         $linktext Optional. Text to display instead of the comment author's email address.
144
 *                                 Default empty.
145
 * @param string         $before   Optional. Text or HTML to display before the email link. Default empty.
146
 * @param string         $after    Optional. Text or HTML to display after the email link. Default empty.
147
 * @param int|WP_Comment $comment  Optional. Comment ID or WP_Comment object. Default is the current comment.
148
 */
149
function comment_author_email_link( $linktext = '', $before = '', $after = '', $comment = null ) {
150
	if ( $link = get_comment_author_email_link( $linktext, $before, $after, $comment ) ) {
151
		echo $link;
152
	}
153
}
154
155
/**
156
 * Return the html email link to the author of the current comment.
157
 *
158
 * Care should be taken to protect the email address and assure that email
159
 * harvesters do not capture your commentors' email address. Most assume that
160
 * their email address will not appear in raw form on the site. Doing so will
161
 * enable anyone, including those that people don't want to get the email
162
 * address and use it for their own means good and bad.
163
 *
164
 * @since 2.7.0
165
 * @since 4.6.0 Added the `$comment` parameter.
166
 *
167
 * @param string         $linktext Optional. Text to display instead of the comment author's email address.
168
 *                                 Default empty.
169
 * @param string         $before   Optional. Text or HTML to display before the email link. Default empty.
170
 * @param string         $after    Optional. Text or HTML to display after the email link. Default empty.
171
 * @param int|WP_Comment $comment  Optional. Comment ID or WP_Comment object. Default is the current comment.
172
 * @return string HTML markup for the comment author email link. By default, the email address is obfuscated
173
 *                via the {@see 'comment_email'} filter with antispambot().
174
 */
175
function get_comment_author_email_link( $linktext = '', $before = '', $after = '', $comment = null ) {
176
	$comment = get_comment( $comment );
177
178
	/**
179
	 * Filters the comment author's email for display.
180
	 *
181
	 * Care should be taken to protect the email address and assure that email
182
	 * harvesters do not capture your commenter's email address.
183
	 *
184
	 * @since 1.2.0
185
	 * @since 4.1.0 The `$comment` parameter was added.
186
	 *
187
	 * @param string     $comment_author_email The comment author's email address.
188
	 * @param WP_Comment $comment              The comment object.
189
	 */
190
	$email = apply_filters( 'comment_email', $comment->comment_author_email, $comment );
191
192
	if ((!empty($email)) && ($email != '@')) {
193
	$display = ($linktext != '') ? $linktext : $email;
194
		$return  = $before;
195
		$return .= sprintf( '<a href="%1$s">%2$s</a>', esc_url( 'mailto:' . $email ), esc_html( $display ) );
196
	 	$return .= $after;
197
		return $return;
198
	} else {
199
		return '';
200
	}
201
}
202
203
/**
204
 * Retrieve the HTML link to the URL of the author of the current comment.
205
 *
206
 * Both get_comment_author_url() and get_comment_author() rely on get_comment(),
207
 * which falls back to the global comment variable if the $comment_ID argument is empty.
208
 *
209
 * @since 1.5.0
210
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
211
 *
212
 * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to get the author's link.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
213
 *									 Default current comment.
214
 * @return string The comment author name or HTML link for author's URL.
215
 */
216
function get_comment_author_link( $comment_ID = 0 ) {
217
	$comment = get_comment( $comment_ID );
218
	$url     = get_comment_author_url( $comment );
219
	$author  = get_comment_author( $comment );
220
221
	if ( empty( $url ) || 'http://' == $url )
222
		$return = $author;
223
	else
224
		$return = "<a href='$url' rel='external nofollow' class='url'>$author</a>";
225
226
	/**
227
	 * Filters the comment author's link for display.
228
	 *
229
	 * @since 1.5.0
230
	 * @since 4.1.0 The `$author` and `$comment_ID` parameters were added.
231
	 *
232
	 * @param string $return     The HTML-formatted comment author link.
233
	 *                           Empty for an invalid URL.
234
	 * @param string $author     The comment author's username.
235
	 * @param int    $comment_ID The comment ID.
236
	 */
237
	return apply_filters( 'get_comment_author_link', $return, $author, $comment->comment_ID );
238
}
239
240
/**
241
 * Display the html link to the url of the author of the current comment.
242
 *
243
 * @since 0.71
244
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
245
 *
246
 * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to print the author's link.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
247
 *									 Default current comment.
248
 */
249
function comment_author_link( $comment_ID = 0 ) {
250
	echo get_comment_author_link( $comment_ID );
251
}
252
253
/**
254
 * Retrieve the IP address of the author of the current comment.
255
 *
256
 * @since 1.5.0
257
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
258
 *
259
 * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to get the author's IP address.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
260
 *									 Default current comment.
261
 * @return string Comment author's IP address.
262
 */
263
function get_comment_author_IP( $comment_ID = 0 ) {
264
	$comment = get_comment( $comment_ID );
265
266
	/**
267
	 * Filters the comment author's returned IP address.
268
	 *
269
	 * @since 1.5.0
270
	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
271
	 *
272
	 * @param string     $comment_author_IP The comment author's IP address.
273
	 * @param int        $comment_ID        The comment ID.
274
	 * @param WP_Comment $comment           The comment object.
275
	 */
276
	return apply_filters( 'get_comment_author_IP', $comment->comment_author_IP, $comment->comment_ID, $comment );
277
}
278
279
/**
280
 * Display the IP address of the author of the current comment.
281
 *
282
 * @since 0.71
283
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
284
 *
285
 * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to print the author's IP address.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
286
 *									 Default current comment.
287
 */
288
function comment_author_IP( $comment_ID = 0 ) {
289
	echo esc_html( get_comment_author_IP( $comment_ID ) );
290
}
291
292
/**
293
 * Retrieve the url of the author of the current comment.
294
 *
295
 * @since 1.5.0
296
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
297
 *
298
 * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to get the author's URL.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
299
 *									 Default current comment.
300
 * @return string Comment author URL.
301
 */
302
function get_comment_author_url( $comment_ID = 0 ) {
303
	$comment = get_comment( $comment_ID );
304
	$url = '';
305
	$id = 0;
306
	if ( ! empty( $comment ) ) {
307
		$author_url = ( 'http://' == $comment->comment_author_url ) ? '' : $comment->comment_author_url;
308
		$url = esc_url( $author_url, array( 'http', 'https' ) );
309
		$id = $comment->ID;
310
	}
311
312
	/**
313
	 * Filters the comment author's URL.
314
	 *
315
	 * @since 1.5.0
316
	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
317
	 *
318
	 * @param string     $url        The comment author's URL.
319
	 * @param int        $comment_ID The comment ID.
320
	 * @param WP_Comment $comment    The comment object.
321
	 */
322
	return apply_filters( 'get_comment_author_url', $url, $id, $comment );
323
}
324
325
/**
326
 * Display the url of the author of the current comment.
327
 *
328
 * @since 0.71
329
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
330
 *
331
 * @param int|WP_Comment $comment_ID Optional. WP_Comment or the ID of the comment for which to print the author's URL.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
332
 *									 Default current comment.
333
 */
334
function comment_author_url( $comment_ID = 0 ) {
335
	$comment    = get_comment( $comment_ID );
336
	$author_url = get_comment_author_url( $comment );
337
338
	/**
339
	 * Filters the comment author's URL for display.
340
	 *
341
	 * @since 1.2.0
342
	 * @since 4.1.0 The `$comment_ID` parameter was added.
343
	 *
344
	 * @param string $author_url The comment author's URL.
345
	 * @param int    $comment_ID The comment ID.
346
	 */
347
	echo apply_filters( 'comment_url', $author_url, $comment->comment_ID );
348
}
349
350
/**
351
 * Retrieves the HTML link of the url of the author of the current comment.
352
 *
353
 * $linktext parameter is only used if the URL does not exist for the comment
354
 * author. If the URL does exist then the URL will be used and the $linktext
355
 * will be ignored.
356
 *
357
 * Encapsulate the HTML link between the $before and $after. So it will appear
358
 * in the order of $before, link, and finally $after.
359
 *
360
 * @since 1.5.0
361
 * @since 4.6.0 Added the `$comment` parameter.
362
 *
363
 * @param string         $linktext Optional. The text to display instead of the comment
364
 *                                 author's email address. Default empty.
365
 * @param string         $before   Optional. The text or HTML to display before the email link.
366
 *                                 Default empty.
367
 * @param string         $after    Optional. The text or HTML to display after the email link.
368
 *                                 Default empty.
369
 * @param int|WP_Comment $comment  Optional. Comment ID or WP_Comment object.
0 ignored issues
show
Consider making the type for parameter $comment a bit more specific; maybe use integer.
Loading history...
370
 *                                 Default is the current comment.
371
 * @return string The HTML link between the $before and $after parameters.
372
 */
373
function get_comment_author_url_link( $linktext = '', $before = '', $after = '', $comment = 0 ) {
374
	$url = get_comment_author_url( $comment );
375
	$display = ($linktext != '') ? $linktext : $url;
376
	$display = str_replace( 'http://www.', '', $display );
377
	$display = str_replace( 'http://', '', $display );
378
379
	if ( '/' == substr($display, -1) ) {
380
		$display = substr($display, 0, -1);
381
	}
382
383
	$return = "$before<a href='$url' rel='external'>$display</a>$after";
384
385
	/**
386
	 * Filters the comment author's returned URL link.
387
	 *
388
	 * @since 1.5.0
389
	 *
390
	 * @param string $return The HTML-formatted comment author URL link.
391
	 */
392
	return apply_filters( 'get_comment_author_url_link', $return );
393
}
394
395
/**
396
 * Displays the HTML link of the url of the author of the current comment.
397
 *
398
 * @since 0.71
399
 * @since 4.6.0 Added the `$comment` parameter.
400
 *
401
 * @param string         $linktext Optional. Text to display instead of the comment author's
402
 *                                 email address. Default empty.
403
 * @param string         $before   Optional. Text or HTML to display before the email link.
404
 *                                 Default empty.
405
 * @param string         $after    Optional. Text or HTML to display after the email link.
406
 *                                 Default empty.
407
 * @param int|WP_Comment $comment  Optional. Comment ID or WP_Comment object.
0 ignored issues
show
Consider making the type for parameter $comment a bit more specific; maybe use integer.
Loading history...
408
 *                                 Default is the current comment.
409
 */
410
function comment_author_url_link( $linktext = '', $before = '', $after = '', $comment = 0 ) {
411
	echo get_comment_author_url_link( $linktext, $before, $after, $comment );
412
}
413
414
/**
415
 * Generates semantic classes for each comment element.
416
 *
417
 * @since 2.7.0
418
 * @since 4.4.0 Added the ability for `$comment` to also accept a WP_Comment object.
419
 *
420
 * @param string|array   $class    Optional. One or more classes to add to the class list.
421
 *                                 Default empty.
422
 * @param int|WP_Comment $comment  Comment ID or WP_Comment object. Default current comment.
423
 * @param int|WP_Post    $post_id  Post ID or WP_Post object. Default current post.
424
 * @param bool           $echo     Optional. Whether to cho or return the output.
425
 *                                 Default true.
426
 * @return string If `$echo` is false, the class will be returned. Void otherwise.
0 ignored issues
show
Should the return type not be null|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
427
 */
428
function comment_class( $class = '', $comment = null, $post_id = null, $echo = true ) {
429
	// Separates classes with a single space, collates classes for comment DIV
430
	$class = 'class="' . join( ' ', get_comment_class( $class, $comment, $post_id ) ) . '"';
431
	if ( $echo)
432
		echo $class;
433
	else
434
		return $class;
435
}
436
437
/**
438
 * Returns the classes for the comment div as an array.
439
 *
440
 * @since 2.7.0
441
 * @since 4.4.0 Added the ability for `$comment_id` to also accept a WP_Comment object.
442
 *
443
 * @global int $comment_alt
444
 * @global int $comment_depth
445
 * @global int $comment_thread_alt
446
 *
447
 * @param string|array   $class      Optional. One or more classes to add to the class list. Default empty.
448
 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. Default current comment.
449
 * @param int|WP_Post    $post_id    Post ID or WP_Post object. Default current post.
450
 * @return array An array of classes.
451
 */
452
function get_comment_class( $class = '', $comment_id = null, $post_id = null ) {
453
	global $comment_alt, $comment_depth, $comment_thread_alt;
454
455
	$classes = array();
456
457
	$comment = get_comment( $comment_id );
458
	if ( ! $comment ) {
459
		return $classes;
460
	}
461
462
	// Get the comment type (comment, trackback),
463
	$classes[] = ( empty( $comment->comment_type ) ) ? 'comment' : $comment->comment_type;
464
465
	// Add classes for comment authors that are registered users.
466
	if ( $comment->user_id > 0 && $user = get_userdata( $comment->user_id ) ) {
467
		$classes[] = 'byuser';
468
		$classes[] = 'comment-author-' . sanitize_html_class( $user->user_nicename, $comment->user_id );
469
		// For comment authors who are the author of the post
470
		if ( $post = get_post($post_id) ) {
471
			if ( $comment->user_id === $post->post_author ) {
472
				$classes[] = 'bypostauthor';
473
			}
474
		}
475
	}
476
477
	if ( empty($comment_alt) )
478
		$comment_alt = 0;
479
	if ( empty($comment_depth) )
480
		$comment_depth = 1;
481
	if ( empty($comment_thread_alt) )
482
		$comment_thread_alt = 0;
483
484
	if ( $comment_alt % 2 ) {
485
		$classes[] = 'odd';
486
		$classes[] = 'alt';
487
	} else {
488
		$classes[] = 'even';
489
	}
490
491
	$comment_alt++;
492
493
	// Alt for top-level comments
494
	if ( 1 == $comment_depth ) {
495
		if ( $comment_thread_alt % 2 ) {
496
			$classes[] = 'thread-odd';
497
			$classes[] = 'thread-alt';
498
		} else {
499
			$classes[] = 'thread-even';
500
		}
501
		$comment_thread_alt++;
502
	}
503
504
	$classes[] = "depth-$comment_depth";
505
506 View Code Duplication
	if ( !empty($class) ) {
507
		if ( !is_array( $class ) )
508
			$class = preg_split('#\s+#', $class);
509
		$classes = array_merge($classes, $class);
510
	}
511
512
	$classes = array_map('esc_attr', $classes);
513
514
	/**
515
	 * Filters the returned CSS classes for the current comment.
516
	 *
517
	 * @since 2.7.0
518
	 *
519
	 * @param array       $classes    An array of comment classes.
520
	 * @param string      $class      A comma-separated list of additional classes added to the list.
521
	 * @param int         $comment_id The comment id.
522
	 * @param WP_Comment  $comment    The comment object.
523
	 * @param int|WP_Post $post_id    The post ID or WP_Post object.
524
	 */
525
	return apply_filters( 'comment_class', $classes, $class, $comment->comment_ID, $comment, $post_id );
526
}
527
528
/**
529
 * Retrieve the comment date of the current comment.
530
 *
531
 * @since 1.5.0
532
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
533
 *
534
 * @param string          $d          Optional. The format of the date. Default user's setting.
535
 * @param int|WP_Comment  $comment_ID WP_Comment or ID of the comment for which to get the date.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
536
 *                                    Default current comment.
537
 * @return string The comment's date.
538
 */
539
function get_comment_date( $d = '', $comment_ID = 0 ) {
540
	$comment = get_comment( $comment_ID );
541 View Code Duplication
	if ( '' == $d )
542
		$date = mysql2date(get_option('date_format'), $comment->comment_date);
543
	else
544
		$date = mysql2date($d, $comment->comment_date);
545
	/**
546
	 * Filters the returned comment date.
547
	 *
548
	 * @since 1.5.0
549
	 *
550
	 * @param string|int $date    Formatted date string or Unix timestamp.
551
	 * @param string     $d       The format of the date.
552
	 * @param WP_Comment $comment The comment object.
553
	 */
554
	return apply_filters( 'get_comment_date', $date, $d, $comment );
555
}
556
557
/**
558
 * Display the comment date of the current comment.
559
 *
560
 * @since 0.71
561
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
562
 *
563
 * @param string         $d          Optional. The format of the date. Default user's settings.
564
 * @param int|WP_Comment $comment_ID WP_Comment or ID of the comment for which to print the date.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
565
 *                                   Default current comment.
566
 */
567
function comment_date( $d = '', $comment_ID = 0 ) {
568
	echo get_comment_date( $d, $comment_ID );
569
}
570
571
/**
572
 * Retrieve the excerpt of the current comment.
573
 *
574
 * Will cut each word and only output the first 20 words with '&hellip;' at the end.
575
 * If the word count is less than 20, then no truncating is done and no '&hellip;'
576
 * will appear.
577
 *
578
 * @since 1.5.0
579
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
580
 *
581
 * @param int|WP_Comment $comment_ID  WP_Comment or ID of the comment for which to get the excerpt.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
582
 *                                    Default current comment.
583
 * @return string The maybe truncated comment with 20 words or less.
584
 */
585
function get_comment_excerpt( $comment_ID = 0 ) {
586
	$comment = get_comment( $comment_ID );
587
	$comment_text = strip_tags( str_replace( array( "\n", "\r" ), ' ', $comment->comment_content ) );
588
	$words = explode( ' ', $comment_text );
589
590
	/**
591
	 * Filters the amount of words used in the comment excerpt.
592
	 *
593
	 * @since 4.4.0
594
	 *
595
	 * @param int $comment_excerpt_length The amount of words you want to display in the comment excerpt.
596
	 */
597
	$comment_excerpt_length = apply_filters( 'comment_excerpt_length', 20 );
598
599
	$use_ellipsis = count( $words ) > $comment_excerpt_length;
600
	if ( $use_ellipsis ) {
601
		$words = array_slice( $words, 0, $comment_excerpt_length );
602
	}
603
604
	$excerpt = trim( join( ' ', $words ) );
605
	if ( $use_ellipsis ) {
606
		$excerpt .= '&hellip;';
607
	}
608
	/**
609
	 * Filters the retrieved comment excerpt.
610
	 *
611
	 * @since 1.5.0
612
	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
613
	 *
614
	 * @param string     $excerpt    The comment excerpt text.
615
	 * @param int        $comment_ID The comment ID.
616
	 * @param WP_Comment $comment    The comment object.
617
	 */
618
	return apply_filters( 'get_comment_excerpt', $excerpt, $comment->comment_ID, $comment );
619
}
620
621
/**
622
 * Display the excerpt of the current comment.
623
 *
624
 * @since 1.2.0
625
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
626
 *
627
 * @param int|WP_Comment $comment_ID  WP_Comment or ID of the comment for which to print the excerpt.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
628
 *                                    Default current comment.
629
 */
630
function comment_excerpt( $comment_ID = 0 ) {
631
	$comment         = get_comment( $comment_ID );
632
	$comment_excerpt = get_comment_excerpt( $comment );
633
634
	/**
635
	 * Filters the comment excerpt for display.
636
	 *
637
	 * @since 1.2.0
638
	 * @since 4.1.0 The `$comment_ID` parameter was added.
639
	 *
640
	 * @param string $comment_excerpt The comment excerpt text.
641
	 * @param int    $comment_ID      The comment ID.
642
	 */
643
	echo apply_filters( 'comment_excerpt', $comment_excerpt, $comment->comment_ID );
644
}
645
646
/**
647
 * Retrieve the comment id of the current comment.
648
 *
649
 * @since 1.5.0
650
 *
651
 * @return int The comment ID.
652
 */
653
function get_comment_ID() {
654
	$comment = get_comment();
655
656
	/**
657
	 * Filters the returned comment ID.
658
	 *
659
	 * @since 1.5.0
660
	 * @since 4.1.0 The `$comment_ID` parameter was added.
661
	 *
662
	 * @param int        $comment_ID The current comment ID.
663
	 * @param WP_Comment $comment    The comment object.
664
	 */
665
	return apply_filters( 'get_comment_ID', $comment->comment_ID, $comment );
666
}
667
668
/**
669
 * Display the comment id of the current comment.
670
 *
671
 * @since 0.71
672
 */
673
function comment_ID() {
674
	echo get_comment_ID();
675
}
676
677
/**
678
 * Retrieve the link to a given comment.
679
 *
680
 * @since 1.5.0
681
 * @since 4.4.0 Added the ability for `$comment` to also accept a WP_Comment object. Added `$cpage` argument.
682
 *
683
 * @see get_page_of_comment()
684
 *
685
 * @global WP_Rewrite $wp_rewrite
686
 * @global bool       $in_comment_loop
687
 *
688
 * @param WP_Comment|int|null $comment Comment to retrieve. Default current comment.
689
 * @param array               $args {
690
 *     An array of optional arguments to override the defaults.
691
 *
692
 *     @type string     $type      Passed to get_page_of_comment().
693
 *     @type int        $page      Current page of comments, for calculating comment pagination.
694
 *     @type int        $per_page  Per-page value for comment pagination.
695
 *     @type int        $max_depth Passed to get_page_of_comment().
696
 *     @type int|string $cpage     Value to use for the comment's "comment-page" or "cpage" value.
697
 *                                 If provided, this value overrides any value calculated from `$page`
698
 *                                 and `$per_page`.
699
 * }
700
 * @return string The permalink to the given comment.
701
 */
702
function get_comment_link( $comment = null, $args = array() ) {
703
	global $wp_rewrite, $in_comment_loop;
704
705
	$comment = get_comment($comment);
706
707
	// Back-compat.
708
	if ( ! is_array( $args ) ) {
709
		$args = array( 'page' => $args );
710
	}
711
712
	$defaults = array(
713
		'type'      => 'all',
714
		'page'      => '',
715
		'per_page'  => '',
716
		'max_depth' => '',
717
		'cpage'     => null,
718
	);
719
	$args = wp_parse_args( $args, $defaults );
720
721
	$link = get_permalink( $comment->comment_post_ID );
722
723
	// The 'cpage' param takes precedence.
724
	if ( ! is_null( $args['cpage'] ) ) {
725
		$cpage = $args['cpage'];
726
727
	// No 'cpage' is provided, so we calculate one.
728
	} else {
729 View Code Duplication
		if ( '' === $args['per_page'] && get_option( 'page_comments' ) ) {
730
			$args['per_page'] = get_option('comments_per_page');
731
		}
732
733
		if ( empty( $args['per_page'] ) ) {
734
			$args['per_page'] = 0;
735
			$args['page'] = 0;
736
		}
737
738
		$cpage = $args['page'];
739
740
		if ( '' == $cpage ) {
741
			if ( ! empty( $in_comment_loop ) ) {
742
				$cpage = get_query_var( 'cpage' );
743
			} else {
744
				// Requires a database hit, so we only do it when we can't figure out from context.
745
				$cpage = get_page_of_comment( $comment->comment_ID, $args );
746
			}
747
		}
748
749
		/*
750
		 * If the default page displays the oldest comments, the permalinks for comments on the default page
751
		 * do not need a 'cpage' query var.
752
		 */
753
		if ( 'oldest' === get_option( 'default_comments_page' ) && 1 === $cpage ) {
754
			$cpage = '';
755
		}
756
	}
757
758
	if ( $cpage && get_option( 'page_comments' ) ) {
759
		if ( $wp_rewrite->using_permalinks() ) {
760
			if ( $cpage ) {
761
				$link = trailingslashit( $link ) . $wp_rewrite->comments_pagination_base . '-' . $cpage;
0 ignored issues
show
It seems like $link can also be of type false; however, trailingslashit() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
762
			}
763
764
			$link = user_trailingslashit( $link, 'comment' );
0 ignored issues
show
It seems like $link can also be of type false; however, user_trailingslashit() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
765
		} elseif ( $cpage ) {
766
			$link = add_query_arg( 'cpage', $cpage, $link );
767
		}
768
769
	}
770
771
	if ( $wp_rewrite->using_permalinks() ) {
772
		$link = user_trailingslashit( $link, 'comment' );
0 ignored issues
show
It seems like $link can also be of type false; however, user_trailingslashit() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
773
	}
774
775
	$link = $link . '#comment-' . $comment->comment_ID;
776
777
	/**
778
	 * Filters the returned single comment permalink.
779
	 *
780
	 * @since 2.8.0
781
	 * @since 4.4.0 Added the `$cpage` parameter.
782
	 *
783
	 * @see get_page_of_comment()
784
	 *
785
	 * @param string     $link    The comment permalink with '#comment-$id' appended.
786
	 * @param WP_Comment $comment The current comment object.
787
	 * @param array      $args    An array of arguments to override the defaults.
788
	 * @param int        $cpage   The calculated 'cpage' value.
789
	 */
790
	return apply_filters( 'get_comment_link', $link, $comment, $args, $cpage );
791
}
792
793
/**
794
 * Retrieves the link to the current post comments.
795
 *
796
 * @since 1.5.0
797
 *
798
 * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is global $post.
0 ignored issues
show
Consider making the type for parameter $post_id a bit more specific; maybe use integer.
Loading history...
799
 * @return string The link to the comments.
800
 */
801
function get_comments_link( $post_id = 0 ) {
802
	$hash = get_comments_number( $post_id ) ? '#comments' : '#respond';
803
	$comments_link = get_permalink( $post_id ) . $hash;
804
805
	/**
806
	 * Filters the returned post comments permalink.
807
	 *
808
	 * @since 3.6.0
809
	 *
810
	 * @param string      $comments_link Post comments permalink with '#comments' appended.
811
	 * @param int|WP_Post $post_id       Post ID or WP_Post object.
812
	 */
813
	return apply_filters( 'get_comments_link', $comments_link, $post_id );
814
}
815
816
/**
817
 * Display the link to the current post comments.
818
 *
819
 * @since 0.71
820
 *
821
 * @param string $deprecated   Not Used.
822
 * @param string $deprecated_2 Not Used.
823
 */
824
function comments_link( $deprecated = '', $deprecated_2 = '' ) {
825
	if ( !empty( $deprecated ) )
826
		_deprecated_argument( __FUNCTION__, '0.72' );
827
	if ( !empty( $deprecated_2 ) )
828
		_deprecated_argument( __FUNCTION__, '1.3.0' );
829
	echo esc_url( get_comments_link() );
830
}
831
832
/**
833
 * Retrieve the amount of comments a post has.
834
 *
835
 * @since 1.5.0
836
 *
837
 * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is global $post.
0 ignored issues
show
Consider making the type for parameter $post_id a bit more specific; maybe use integer.
Loading history...
838
 * @return int The number of comments a post has.
839
 */
840
function get_comments_number( $post_id = 0 ) {
841
	$post = get_post( $post_id );
842
843
	if ( ! $post ) {
844
		$count = 0;
845
	} else {
846
		$count = $post->comment_count;
847
		$post_id = $post->ID;
848
	}
849
850
	/**
851
	 * Filters the returned comment count for a post.
852
	 *
853
	 * @since 1.5.0
854
	 *
855
	 * @param int $count   Number of comments a post has.
856
	 * @param int $post_id Post ID.
857
	 */
858
	return apply_filters( 'get_comments_number', $count, $post_id );
859
}
860
861
/**
862
 * Display the language string for the number of comments the current post has.
863
 *
864
 * @since 0.71
865
 *
866
 * @param string $zero       Optional. Text for no comments. Default false.
867
 * @param string $one        Optional. Text for one comment. Default false.
868
 * @param string $more       Optional. Text for more than one comment. Default false.
869
 * @param string $deprecated Not used.
870
 */
871
function comments_number( $zero = false, $one = false, $more = false, $deprecated = '' ) {
872
	if ( ! empty( $deprecated ) ) {
873
		_deprecated_argument( __FUNCTION__, '1.3.0' );
874
	}
875
	echo get_comments_number_text( $zero, $one, $more );
876
}
877
878
/**
879
 * Display the language string for the number of comments the current post has.
880
 *
881
 * @since 4.0.0
882
 *
883
 * @param string $zero Optional. Text for no comments. Default false.
884
 * @param string $one  Optional. Text for one comment. Default false.
885
 * @param string $more Optional. Text for more than one comment. Default false.
886
 */
887
function get_comments_number_text( $zero = false, $one = false, $more = false ) {
888
	$number = get_comments_number();
889
890
	if ( $number > 1 ) {
891
		if ( false === $more ) {
892
			/* translators: %s: number of comments */
893
			$output = sprintf( _n( '%s Comment', '%s Comments', $number ), number_format_i18n( $number ) );
894
		} else {
895
			// % Comments
896
			/* translators: If comment number in your language requires declension,
897
			 * translate this to 'on'. Do not translate into your own language.
898
			 */
899
			if ( 'on' === _x( 'off', 'Comment number declension: on or off' ) ) {
900
				$text = preg_replace( '#<span class="screen-reader-text">.+?</span>#', '', $more );
901
				$text = preg_replace( '/&.+?;/', '', $text ); // Kill entities
902
				$text = trim( strip_tags( $text ), '% ' );
903
904
				// Replace '% Comments' with a proper plural form
905
				if ( $text && ! preg_match( '/[0-9]+/', $text ) && false !== strpos( $more, '%' ) ) {
906
					/* translators: %s: number of comments */
907
					$new_text = _n( '%s Comment', '%s Comments', $number );
908
					$new_text = trim( sprintf( $new_text, '' ) );
909
910
					$more = str_replace( $text, $new_text, $more );
911
					if ( false === strpos( $more, '%' ) ) {
912
						$more = '% ' . $more;
913
					}
914
				}
915
			}
916
917
			$output = str_replace( '%', number_format_i18n( $number ), $more );
918
		}
919
	} elseif ( $number == 0 ) {
920
		$output = ( false === $zero ) ? __( 'No Comments' ) : $zero;
921
	} else { // must be one
922
		$output = ( false === $one ) ? __( '1 Comment' ) : $one;
923
	}
924
	/**
925
	 * Filters the comments count for display.
926
	 *
927
	 * @since 1.5.0
928
	 *
929
	 * @see _n()
930
	 *
931
	 * @param string $output A translatable string formatted based on whether the count
932
	 *                       is equal to 0, 1, or 1+.
933
	 * @param int    $number The number of post comments.
934
	 */
935
	return apply_filters( 'comments_number', $output, $number );
936
}
937
938
/**
939
 * Retrieve the text of the current comment.
940
 *
941
 * @since 1.5.0
942
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
943
 *
944
 * @see Walker_Comment::comment()
945
 *
946
 * @param int|WP_Comment  $comment_ID WP_Comment or ID of the comment for which to get the text.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
947
 *                                    Default current comment.
948
 * @param array           $args       Optional. An array of arguments. Default empty.
949
 * @return string The comment content.
950
 */
951
function get_comment_text( $comment_ID = 0, $args = array() ) {
952
	$comment = get_comment( $comment_ID );
953
954
	/**
955
	 * Filters the text of a comment.
956
	 *
957
	 * @since 1.5.0
958
	 *
959
	 * @see Walker_Comment::comment()
960
	 *
961
	 * @param string     $comment_content Text of the comment.
962
	 * @param WP_Comment $comment         The comment object.
963
	 * @param array      $args            An array of arguments.
964
	 */
965
	return apply_filters( 'get_comment_text', $comment->comment_content, $comment, $args );
966
}
967
968
/**
969
 * Display the text of the current comment.
970
 *
971
 * @since 0.71
972
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
973
 *
974
 * @see Walker_Comment::comment()
975
 *
976
 * @param int|WP_Comment  $comment_ID WP_Comment or ID of the comment for which to print the text.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
977
 *                                    Default current comment.
978
 * @param array           $args       Optional. An array of arguments. Default empty array. Default empty.
979
 */
980
function comment_text( $comment_ID = 0, $args = array() ) {
981
	$comment = get_comment( $comment_ID );
982
983
	$comment_text = get_comment_text( $comment, $args );
984
	/**
985
	 * Filters the text of a comment to be displayed.
986
	 *
987
	 * @since 1.2.0
988
	 *
989
	 * @see Walker_Comment::comment()
990
	 *
991
	 * @param string          $comment_text Text of the current comment.
992
	 * @param WP_Comment|null $comment      The comment object.
993
	 * @param array           $args         An array of arguments.
994
	 */
995
	echo apply_filters( 'comment_text', $comment_text, $comment, $args );
996
}
997
998
/**
999
 * Retrieve the comment time of the current comment.
1000
 *
1001
 * @since 1.5.0
1002
 *
1003
 * @param string $d         Optional. The format of the time. Default user's settings.
1004
 * @param bool   $gmt       Optional. Whether to use the GMT date. Default false.
1005
 * @param bool   $translate Optional. Whether to translate the time (for use in feeds).
1006
 *                          Default true.
1007
 * @return string The formatted time.
1008
 */
1009
function get_comment_time( $d = '', $gmt = false, $translate = true ) {
1010
	$comment = get_comment();
1011
1012
	$comment_date = $gmt ? $comment->comment_date_gmt : $comment->comment_date;
1013 View Code Duplication
	if ( '' == $d )
1014
		$date = mysql2date(get_option('time_format'), $comment_date, $translate);
1015
	else
1016
		$date = mysql2date($d, $comment_date, $translate);
1017
1018
	/**
1019
	 * Filters the returned comment time.
1020
	 *
1021
	 * @since 1.5.0
1022
	 *
1023
	 * @param string|int $date      The comment time, formatted as a date string or Unix timestamp.
1024
	 * @param string     $d         Date format.
1025
	 * @param bool       $gmt       Whether the GMT date is in use.
1026
	 * @param bool       $translate Whether the time is translated.
1027
	 * @param WP_Comment $comment   The comment object.
1028
	 */
1029
	return apply_filters( 'get_comment_time', $date, $d, $gmt, $translate, $comment );
1030
}
1031
1032
/**
1033
 * Display the comment time of the current comment.
1034
 *
1035
 * @since 0.71
1036
 *
1037
 * @param string $d Optional. The format of the time. Default user's settings.
1038
 */
1039
function comment_time( $d = '' ) {
1040
	echo get_comment_time($d);
1041
}
1042
1043
/**
1044
 * Retrieve the comment type of the current comment.
1045
 *
1046
 * @since 1.5.0
1047
 * @since 4.4.0 Added the ability for `$comment_ID` to also accept a WP_Comment object.
1048
 *
1049
 * @param int|WP_Comment $comment_ID Optional. WP_Comment or ID of the comment for which to get the type.
0 ignored issues
show
Consider making the type for parameter $comment_ID a bit more specific; maybe use integer.
Loading history...
1050
 *                                   Default current comment.
1051
 * @return string The comment type.
1052
 */
1053
function get_comment_type( $comment_ID = 0 ) {
1054
	$comment = get_comment( $comment_ID );
1055
	if ( '' == $comment->comment_type )
1056
		$comment->comment_type = 'comment';
1057
1058
	/**
1059
	 * Filters the returned comment type.
1060
	 *
1061
	 * @since 1.5.0
1062
	 * @since 4.1.0 The `$comment_ID` and `$comment` parameters were added.
1063
	 *
1064
	 * @param string     $comment_type The type of comment, such as 'comment', 'pingback', or 'trackback'.
1065
	 * @param int 	     $comment_ID   The comment ID.
1066
	 * @param WP_Comment $comment      The comment object.
1067
	 */
1068
	return apply_filters( 'get_comment_type', $comment->comment_type, $comment->comment_ID, $comment );
1069
}
1070
1071
/**
1072
 * Display the comment type of the current comment.
1073
 *
1074
 * @since 0.71
1075
 *
1076
 * @param string $commenttxt   Optional. String to display for comment type. Default false.
1077
 * @param string $trackbacktxt Optional. String to display for trackback type. Default false.
1078
 * @param string $pingbacktxt  Optional. String to display for pingback type. Default false.
1079
 */
1080
function comment_type( $commenttxt = false, $trackbacktxt = false, $pingbacktxt = false ) {
1081
	if ( false === $commenttxt ) $commenttxt = _x( 'Comment', 'noun' );
1082
	if ( false === $trackbacktxt ) $trackbacktxt = __( 'Trackback' );
1083
	if ( false === $pingbacktxt ) $pingbacktxt = __( 'Pingback' );
1084
	$type = get_comment_type();
1085
	switch( $type ) {
1086
		case 'trackback' :
1087
			echo $trackbacktxt;
1088
			break;
1089
		case 'pingback' :
1090
			echo $pingbacktxt;
1091
			break;
1092
		default :
1093
			echo $commenttxt;
1094
	}
1095
}
1096
1097
/**
1098
 * Retrieve The current post's trackback URL.
1099
 *
1100
 * There is a check to see if permalink's have been enabled and if so, will
1101
 * retrieve the pretty path. If permalinks weren't enabled, the ID of the
1102
 * current post is used and appended to the correct page to go to.
1103
 *
1104
 * @since 1.5.0
1105
 *
1106
 * @return string The trackback URL after being filtered.
1107
 */
1108
function get_trackback_url() {
1109
	if ( '' != get_option('permalink_structure') )
1110
		$tb_url = trailingslashit(get_permalink()) . user_trailingslashit('trackback', 'single_trackback');
0 ignored issues
show
It seems like get_permalink() can also be of type false; however, trailingslashit() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1111
	else
1112
		$tb_url = get_option('siteurl') . '/wp-trackback.php?p=' . get_the_ID();
1113
1114
	/**
1115
	 * Filters the returned trackback URL.
1116
	 *
1117
	 * @since 2.2.0
1118
	 *
1119
	 * @param string $tb_url The trackback URL.
1120
	 */
1121
	return apply_filters( 'trackback_url', $tb_url );
1122
}
1123
1124
/**
1125
 * Display the current post's trackback URL.
1126
 *
1127
 * @since 0.71
1128
 *
1129
 * @param bool $deprecated_echo Not used.
1130
 * @return void|string Should only be used to echo the trackback URL, use get_trackback_url()
1131
 *                     for the result instead.
1132
 */
1133
function trackback_url( $deprecated_echo = true ) {
1134
	if ( true !== $deprecated_echo ) {
1135
		_deprecated_argument( __FUNCTION__, '2.5.0',
1136
			/* translators: %s: get_trackback_url() */
1137
			sprintf( __( 'Use %s instead if you do not want the value echoed.' ),
1138
				'<code>get_trackback_url()</code>'
1139
			)
1140
		);
1141
	}
1142
1143
	if ( $deprecated_echo ) {
1144
		echo get_trackback_url();
1145
	} else {
1146
		return get_trackback_url();
1147
	}
1148
}
1149
1150
/**
1151
 * Generate and display the RDF for the trackback information of current post.
1152
 *
1153
 * Deprecated in 3.0.0, and restored in 3.0.1.
1154
 *
1155
 * @since 0.71
1156
 *
1157
 * @param int $deprecated Not used (Was $timezone = 0).
1158
 */
1159
function trackback_rdf( $deprecated = '' ) {
1160
	if ( ! empty( $deprecated ) ) {
1161
		_deprecated_argument( __FUNCTION__, '2.5.0' );
1162
	}
1163
1164
	if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && false !== stripos( $_SERVER['HTTP_USER_AGENT'], 'W3C_Validator' ) ) {
1165
		return;
1166
	}
1167
1168
	echo '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
1169
			xmlns:dc="http://purl.org/dc/elements/1.1/"
1170
			xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
1171
		<rdf:Description rdf:about="';
1172
	the_permalink();
1173
	echo '"'."\n";
1174
	echo '    dc:identifier="';
1175
	the_permalink();
1176
	echo '"'."\n";
1177
	echo '    dc:title="'.str_replace('--', '&#x2d;&#x2d;', wptexturize(strip_tags(get_the_title()))).'"'."\n";
1178
	echo '    trackback:ping="'.get_trackback_url().'"'." />\n";
1179
	echo '</rdf:RDF>';
1180
}
1181
1182
/**
1183
 * Whether the current post is open for comments.
1184
 *
1185
 * @since 1.5.0
1186
 *
1187
 * @param int|WP_Post $post_id Post ID or WP_Post object. Default current post.
1188
 * @return bool True if the comments are open.
1189
 */
1190 View Code Duplication
function comments_open( $post_id = null ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1191
1192
	$_post = get_post($post_id);
1193
1194
	$post_id = $_post ? $_post->ID : 0;
1195
	$open = ( 'open' == $_post->comment_status );
1196
1197
	/**
1198
	 * Filters whether the current post is open for comments.
1199
	 *
1200
	 * @since 2.5.0
1201
	 *
1202
	 * @param bool $open    Whether the current post is open for comments.
1203
	 * @param int  $post_id The post ID.
1204
	 */
1205
	return apply_filters( 'comments_open', $open, $post_id );
1206
}
1207
1208
/**
1209
 * Whether the current post is open for pings.
1210
 *
1211
 * @since 1.5.0
1212
 *
1213
 * @param int|WP_Post $post_id Post ID or WP_Post object. Default current post.
1214
 * @return bool True if pings are accepted
1215
 */
1216 View Code Duplication
function pings_open( $post_id = null ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1217
1218
	$_post = get_post($post_id);
1219
1220
	$post_id = $_post ? $_post->ID : 0;
1221
	$open = ( 'open' == $_post->ping_status );
1222
1223
	/**
1224
	 * Filters whether the current post is open for pings.
1225
	 *
1226
	 * @since 2.5.0
1227
	 *
1228
	 * @param bool $open    Whether the current post is open for pings.
1229
	 * @param int  $post_id The post ID.
1230
	 */
1231
	return apply_filters( 'pings_open', $open, $post_id );
1232
}
1233
1234
/**
1235
 * Display form token for unfiltered comments.
1236
 *
1237
 * Will only display nonce token if the current user has permissions for
1238
 * unfiltered html. Won't display the token for other users.
1239
 *
1240
 * The function was backported to 2.0.10 and was added to versions 2.1.3 and
1241
 * above. Does not exist in versions prior to 2.0.10 in the 2.0 branch and in
1242
 * the 2.1 branch, prior to 2.1.3. Technically added in 2.2.0.
1243
 *
1244
 * Backported to 2.0.10.
1245
 *
1246
 * @since 2.1.3
1247
 */
1248
function wp_comment_form_unfiltered_html_nonce() {
1249
	$post = get_post();
1250
	$post_id = $post ? $post->ID : 0;
1251
1252
	if ( current_user_can( 'unfiltered_html' ) ) {
1253
		wp_nonce_field( 'unfiltered-html-comment_' . $post_id, '_wp_unfiltered_html_comment_disabled', false );
1254
		echo "<script>(function(){if(window===window.parent){document.getElementById('_wp_unfiltered_html_comment_disabled').name='_wp_unfiltered_html_comment';}})();</script>\n";
1255
	}
1256
}
1257
1258
/**
1259
 * Load the comment template specified in $file.
1260
 *
1261
 * Will not display the comments template if not on single post or page, or if
1262
 * the post does not have comments.
1263
 *
1264
 * Uses the WordPress database object to query for the comments. The comments
1265
 * are passed through the {@see 'comments_array'} filter hook with the list of comments
1266
 * and the post ID respectively.
1267
 *
1268
 * The `$file` path is passed through a filter hook called {@see 'comments_template'},
1269
 * which includes the TEMPLATEPATH and $file combined. Tries the $filtered path
1270
 * first and if it fails it will require the default comment template from the
1271
 * default theme. If either does not exist, then the WordPress process will be
1272
 * halted. It is advised for that reason, that the default theme is not deleted.
1273
 *
1274
 * Will not try to get the comments if the post has none.
1275
 *
1276
 * @since 1.5.0
1277
 *
1278
 * @global WP_Query   $wp_query
1279
 * @global WP_Post    $post
1280
 * @global wpdb       $wpdb
1281
 * @global int        $id
1282
 * @global WP_Comment $comment
1283
 * @global string     $user_login
1284
 * @global int        $user_ID
1285
 * @global string     $user_identity
1286
 * @global bool       $overridden_cpage
1287
 * @global bool       $withcomments
1288
 *
1289
 * @param string $file              Optional. The file to load. Default '/comments.php'.
1290
 * @param bool   $separate_comments Optional. Whether to separate the comments by comment type.
1291
 *                                  Default false.
1292
 */
1293
function comments_template( $file = '/comments.php', $separate_comments = false ) {
1294
	global $wp_query, $withcomments, $post, $wpdb, $id, $comment, $user_login, $user_ID, $user_identity, $overridden_cpage;
1295
1296
	if ( !(is_single() || is_page() || $withcomments) || empty($post) )
1297
		return;
1298
1299
	if ( empty($file) )
1300
		$file = '/comments.php';
1301
1302
	$req = get_option('require_name_email');
1303
1304
	/*
1305
	 * Comment author information fetched from the comment cookies.
1306
	 */
1307
	$commenter = wp_get_current_commenter();
1308
1309
	/*
1310
	 * The name of the current comment author escaped for use in attributes.
1311
	 * Escaped by sanitize_comment_cookies().
1312
	 */
1313
	$comment_author = $commenter['comment_author'];
1314
1315
	/*
1316
	 * The email address of the current comment author escaped for use in attributes.
1317
	 * Escaped by sanitize_comment_cookies().
1318
	 */
1319
	$comment_author_email = $commenter['comment_author_email'];
1320
1321
	/*
1322
	 * The url of the current comment author escaped for use in attributes.
1323
	 */
1324
	$comment_author_url = esc_url($commenter['comment_author_url']);
1325
1326
	$comment_args = array(
1327
		'orderby' => 'comment_date_gmt',
1328
		'order' => 'ASC',
1329
		'status'  => 'approve',
1330
		'post_id' => $post->ID,
1331
		'no_found_rows' => false,
1332
		'update_comment_meta_cache' => false, // We lazy-load comment meta for performance.
1333
	);
1334
1335
	if ( get_option('thread_comments') ) {
1336
		$comment_args['hierarchical'] = 'threaded';
1337
	} else {
1338
		$comment_args['hierarchical'] = false;
1339
	}
1340
1341
	if ( $user_ID ) {
1342
		$comment_args['include_unapproved'] = array( $user_ID );
1343
	} elseif ( ! empty( $comment_author_email ) ) {
1344
		$comment_args['include_unapproved'] = array( $comment_author_email );
1345
	}
1346
1347
	$per_page = 0;
1348
	if ( get_option( 'page_comments' ) ) {
1349
		$per_page = (int) get_query_var( 'comments_per_page' );
1350
		if ( 0 === $per_page ) {
1351
			$per_page = (int) get_option( 'comments_per_page' );
1352
		}
1353
1354
		$comment_args['number'] = $per_page;
1355
		$page = (int) get_query_var( 'cpage' );
1356
1357
		if ( $page ) {
1358
			$comment_args['offset'] = ( $page - 1 ) * $per_page;
1359
		} elseif ( 'oldest' === get_option( 'default_comments_page' ) ) {
1360
			$comment_args['offset'] = 0;
1361
		} else {
1362
			// If fetching the first page of 'newest', we need a top-level comment count.
1363
			$top_level_query = new WP_Comment_Query();
1364
			$top_level_args  = array(
1365
				'count'   => true,
1366
				'orderby' => false,
1367
				'post_id' => $post->ID,
1368
				'status'  => 'approve',
1369
			);
1370
1371
			if ( $comment_args['hierarchical'] ) {
1372
				$top_level_args['parent'] = 0;
1373
			}
1374
1375
			if ( isset( $comment_args['include_unapproved'] ) ) {
1376
				$top_level_args['include_unapproved'] = $comment_args['include_unapproved'];
1377
			}
1378
1379
			$top_level_count = $top_level_query->query( $top_level_args );
1380
1381
			$comment_args['offset'] = ( ceil( $top_level_count / $per_page ) - 1 ) * $per_page;
1382
		}
1383
	}
1384
1385
	/**
1386
	 * Filters the arguments used to query comments in comments_template().
1387
	 *
1388
	 * @since 4.5.0
1389
	 *
1390
	 * @see WP_Comment_Query::__construct()
1391
	 *
1392
	 * @param array $comment_args {
1393
	 *     Array of WP_Comment_Query arguments.
1394
	 *
1395
	 *     @type string|array $orderby                   Field(s) to order by.
1396
	 *     @type string       $order                     Order of results. Accepts 'ASC' or 'DESC'.
1397
	 *     @type string       $status                    Comment status.
1398
	 *     @type array        $include_unapproved        Array of IDs or email addresses whose unapproved comments
1399
	 *                                                   will be included in results.
1400
	 *     @type int          $post_id                   ID of the post.
1401
	 *     @type bool         $no_found_rows             Whether to refrain from querying for found rows.
1402
	 *     @type bool         $update_comment_meta_cache Whether to prime cache for comment meta.
1403
	 *     @type bool|string  $hierarchical              Whether to query for comments hierarchically.
1404
	 *     @type int          $offset                    Comment offset.
1405
	 *     @type int          $number                    Number of comments to fetch.
1406
	 * }
1407
	 */
1408
	$comment_args = apply_filters( 'comments_template_query_args', $comment_args );
1409
	$comment_query = new WP_Comment_Query( $comment_args );
1410
	$_comments = $comment_query->comments;
1411
1412
	// Trees must be flattened before they're passed to the walker.
1413
	if ( $comment_args['hierarchical'] ) {
1414
		$comments_flat = array();
1415
		foreach ( $_comments as $_comment ) {
1416
			$comments_flat[]  = $_comment;
1417
			$comment_children = $_comment->get_children( array(
1418
				'format' => 'flat',
1419
				'status' => $comment_args['status'],
1420
				'orderby' => $comment_args['orderby']
1421
			) );
1422
1423
			foreach ( $comment_children as $comment_child ) {
1424
				$comments_flat[] = $comment_child;
1425
			}
1426
		}
1427
	} else {
1428
		$comments_flat = $_comments;
1429
	}
1430
1431
	/**
1432
	 * Filters the comments array.
1433
	 *
1434
	 * @since 2.1.0
1435
	 *
1436
	 * @param array $comments Array of comments supplied to the comments template.
1437
	 * @param int   $post_ID  Post ID.
1438
	 */
1439
	$wp_query->comments = apply_filters( 'comments_array', $comments_flat, $post->ID );
1440
1441
	$comments = &$wp_query->comments;
1442
	$wp_query->comment_count = count($wp_query->comments);
1443
	$wp_query->max_num_comment_pages = $comment_query->max_num_pages;
1444
1445
	if ( $separate_comments ) {
1446
		$wp_query->comments_by_type = separate_comments($comments);
1447
		$comments_by_type = &$wp_query->comments_by_type;
1448
	} else {
1449
		$wp_query->comments_by_type = array();
1450
	}
1451
1452
	$overridden_cpage = false;
1453
	if ( '' == get_query_var( 'cpage' ) && $wp_query->max_num_comment_pages > 1 ) {
1454
		set_query_var( 'cpage', 'newest' == get_option('default_comments_page') ? get_comment_pages_count() : 1 );
1455
		$overridden_cpage = true;
1456
	}
1457
1458
	if ( !defined('COMMENTS_TEMPLATE') )
1459
		define('COMMENTS_TEMPLATE', true);
1460
1461
	$theme_template = STYLESHEETPATH . $file;
1462
	/**
1463
	 * Filters the path to the theme template file used for the comments template.
1464
	 *
1465
	 * @since 1.5.1
1466
	 *
1467
	 * @param string $theme_template The path to the theme template file.
1468
	 */
1469
	$include = apply_filters( 'comments_template', $theme_template );
1470
	if ( file_exists( $include ) )
1471
		require( $include );
1472
	elseif ( file_exists( TEMPLATEPATH . $file ) )
1473
		require( TEMPLATEPATH . $file );
1474
	else // Backward compat code will be removed in a future release
1475
		require( ABSPATH . WPINC . '/theme-compat/comments.php');
1476
}
1477
1478
/**
1479
 * Displays the link to the comments for the current post ID.
1480
 *
1481
 * @since 0.71
1482
 *
1483
 * @param string $zero      Optional. String to display when no comments. Default false.
1484
 * @param string $one       Optional. String to display when only one comment is available.
1485
 *                          Default false.
1486
 * @param string $more      Optional. String to display when there are more than one comment.
1487
 *                          Default false.
1488
 * @param string $css_class Optional. CSS class to use for comments. Default empty.
1489
 * @param string $none      Optional. String to display when comments have been turned off.
1490
 *                          Default false.
1491
 */
1492
function comments_popup_link( $zero = false, $one = false, $more = false, $css_class = '', $none = false ) {
1493
	$id = get_the_ID();
1494
	$title = get_the_title();
1495
	$number = get_comments_number( $id );
0 ignored issues
show
It seems like $id defined by get_the_ID() on line 1493 can also be of type false; however, get_comments_number() does only seem to accept integer, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
1496
1497
	if ( false === $zero ) {
1498
		/* translators: %s: post title */
1499
		$zero = sprintf( __( 'No Comments<span class="screen-reader-text"> on %s</span>' ), $title );
1500
	}
1501
1502
	if ( false === $one ) {
1503
		/* translators: %s: post title */
1504
		$one = sprintf( __( '1 Comment<span class="screen-reader-text"> on %s</span>' ), $title );
1505
	}
1506
1507
	if ( false === $more ) {
1508
		/* translators: 1: Number of comments 2: post title */
1509
		$more = _n( '%1$s Comment<span class="screen-reader-text"> on %2$s</span>', '%1$s Comments<span class="screen-reader-text"> on %2$s</span>', $number );
1510
		$more = sprintf( $more, number_format_i18n( $number ), $title );
1511
	}
1512
1513
	if ( false === $none ) {
1514
		/* translators: %s: post title */
1515
		$none = sprintf( __( 'Comments Off<span class="screen-reader-text"> on %s</span>' ), $title );
1516
	}
1517
1518
	if ( 0 == $number && !comments_open() && !pings_open() ) {
1519
		echo '<span' . ((!empty($css_class)) ? ' class="' . esc_attr( $css_class ) . '"' : '') . '>' . $none . '</span>';
1520
		return;
1521
	}
1522
1523
	if ( post_password_required() ) {
1524
		_e( 'Enter your password to view comments.' );
1525
		return;
1526
	}
1527
1528
	echo '<a href="';
1529
	if ( 0 == $number ) {
1530
		$respond_link = get_permalink() . '#respond';
1531
		/**
1532
		 * Filters the respond link when a post has no comments.
1533
		 *
1534
		 * @since 4.4.0
1535
		 *
1536
		 * @param string $respond_link The default response link.
1537
		 * @param integer $id The post ID.
1538
		 */
1539
		echo apply_filters( 'respond_link', $respond_link, $id );
1540
	} else {
1541
		comments_link();
1542
	}
1543
	echo '"';
1544
1545
	if ( !empty( $css_class ) ) {
1546
		echo ' class="'.$css_class.'" ';
1547
	}
1548
1549
	$attributes = '';
1550
	/**
1551
	 * Filters the comments link attributes for display.
1552
	 *
1553
	 * @since 2.5.0
1554
	 *
1555
	 * @param string $attributes The comments link attributes. Default empty.
1556
	 */
1557
	echo apply_filters( 'comments_popup_link_attributes', $attributes );
1558
1559
	echo '>';
1560
	comments_number( $zero, $one, $more );
1561
	echo '</a>';
1562
}
1563
1564
/**
1565
 * Retrieve HTML content for reply to comment link.
1566
 *
1567
 * @since 2.7.0
1568
 * @since 4.4.0 Added the ability for `$comment` to also accept a WP_Comment object.
1569
 *
1570
 * @param array $args {
1571
 *     Optional. Override default arguments.
1572
 *
1573
 *     @type string $add_below  The first part of the selector used to identify the comment to respond below.
1574
 *                              The resulting value is passed as the first parameter to addComment.moveForm(),
1575
 *                              concatenated as $add_below-$comment->comment_ID. Default 'comment'.
1576
 *     @type string $respond_id The selector identifying the responding comment. Passed as the third parameter
1577
 *                              to addComment.moveForm(), and appended to the link URL as a hash value.
1578
 *                              Default 'respond'.
1579
 *     @type string $reply_text The text of the Reply link. Default 'Reply'.
1580
 *     @type string $login_text The text of the link to reply if logged out. Default 'Log in to Reply'.
1581
 *     @type int    $max_depth  The max depth of the comment tree. Default 0.
1582
 *     @type int    $depth      The depth of the new comment. Must be greater than 0 and less than the value
1583
 *                              of the 'thread_comments_depth' option set in Settings > Discussion. Default 0.
1584
 *     @type string $before     The text or HTML to add before the reply link. Default empty.
1585
 *     @type string $after      The text or HTML to add after the reply link. Default empty.
1586
 * }
1587
 * @param int|WP_Comment $comment Comment being replied to. Default current comment.
1588
 * @param int|WP_Post    $post    Post ID or WP_Post object the comment is going to be displayed on.
1589
 *                                Default current post.
1590
 * @return void|false|string Link to show comment form, if successful. False, if comments are closed.
1591
 */
1592
function get_comment_reply_link( $args = array(), $comment = null, $post = null ) {
1593
	$defaults = array(
1594
		'add_below'     => 'comment',
1595
		'respond_id'    => 'respond',
1596
		'reply_text'    => __( 'Reply' ),
1597
		/* translators: Comment reply button text. 1: Comment author name */
1598
		'reply_to_text' => __( 'Reply to %s' ),
1599
		'login_text'    => __( 'Log in to Reply' ),
1600
		'max_depth'     => 0,
1601
		'depth'         => 0,
1602
		'before'        => '',
1603
		'after'         => ''
1604
	);
1605
1606
	$args = wp_parse_args( $args, $defaults );
1607
1608
	if ( 0 == $args['depth'] || $args['max_depth'] <= $args['depth'] ) {
1609
		return;
1610
	}
1611
1612
	$comment = get_comment( $comment );
1613
1614
	if ( empty( $post ) ) {
1615
		$post = $comment->comment_post_ID;
1616
	}
1617
1618
	$post = get_post( $post );
1619
1620
	if ( ! comments_open( $post->ID ) ) {
1621
		return false;
1622
	}
1623
1624
	/**
1625
	 * Filters the comment reply link arguments.
1626
	 *
1627
	 * @since 4.1.0
1628
	 *
1629
	 * @param array      $args    Comment reply link arguments. See get_comment_reply_link()
1630
	 *                            for more information on accepted arguments.
1631
	 * @param WP_Comment $comment The object of the comment being replied to.
1632
	 * @param WP_Post    $post    The WP_Post object.
1633
	 */
1634
	$args = apply_filters( 'comment_reply_link_args', $args, $comment, $post );
1635
1636
	if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
1637
		$link = sprintf( '<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
1638
			esc_url( wp_login_url( get_permalink() ) ),
0 ignored issues
show
It seems like get_permalink() can also be of type false; however, wp_login_url() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1639
			$args['login_text']
1640
		);
1641
	} else {
1642
		$onclick = sprintf( 'return addComment.moveForm( "%1$s-%2$s", "%2$s", "%3$s", "%4$s" )',
1643
			$args['add_below'], $comment->comment_ID, $args['respond_id'], $post->ID
1644
		);
1645
1646
		$link = sprintf( "<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s' aria-label='%s'>%s</a>",
1647
			esc_url( add_query_arg( 'replytocom', $comment->comment_ID, get_permalink( $post->ID ) ) ) . "#" . $args['respond_id'],
1648
			$onclick,
1649
			esc_attr( sprintf( $args['reply_to_text'], $comment->comment_author ) ),
1650
			$args['reply_text']
1651
		);
1652
	}
1653
1654
	/**
1655
	 * Filters the comment reply link.
1656
	 *
1657
	 * @since 2.7.0
1658
	 *
1659
	 * @param string  $link    The HTML markup for the comment reply link.
1660
	 * @param array   $args    An array of arguments overriding the defaults.
1661
	 * @param object  $comment The object of the comment being replied.
1662
	 * @param WP_Post $post    The WP_Post object.
1663
	 */
1664
	return apply_filters( 'comment_reply_link', $args['before'] . $link . $args['after'], $args, $comment, $post );
1665
}
1666
1667
/**
1668
 * Displays the HTML content for reply to comment link.
1669
 *
1670
 * @since 2.7.0
1671
 *
1672
 * @see get_comment_reply_link()
1673
 *
1674
 * @param array       $args    Optional. Override default options.
1675
 * @param int         $comment Comment being replied to. Default current comment.
1676
 * @param int|WP_Post $post    Post ID or WP_Post object the comment is going to be displayed on.
1677
 *                             Default current post.
1678
 * @return mixed Link to show comment form, if successful. False, if comments are closed.
1679
 */
1680
function comment_reply_link($args = array(), $comment = null, $post = null) {
1681
	echo get_comment_reply_link($args, $comment, $post);
1682
}
1683
1684
/**
1685
 * Retrieve HTML content for reply to post link.
1686
 *
1687
 * @since 2.7.0
1688
 *
1689
 * @param array $args {
1690
 *     Optional. Override default arguments.
1691
 *
1692
 *     @type string $add_below  The first part of the selector used to identify the comment to respond below.
1693
 *                              The resulting value is passed as the first parameter to addComment.moveForm(),
1694
 *                              concatenated as $add_below-$comment->comment_ID. Default is 'post'.
1695
 *     @type string $respond_id The selector identifying the responding comment. Passed as the third parameter
1696
 *                              to addComment.moveForm(), and appended to the link URL as a hash value.
1697
 *                              Default 'respond'.
1698
 *     @type string $reply_text Text of the Reply link. Default is 'Leave a Comment'.
1699
 *     @type string $login_text Text of the link to reply if logged out. Default is 'Log in to leave a Comment'.
1700
 *     @type string $before     Text or HTML to add before the reply link. Default empty.
1701
 *     @type string $after      Text or HTML to add after the reply link. Default empty.
1702
 * }
1703
 * @param int|WP_Post $post    Optional. Post ID or WP_Post object the comment is going to be displayed on.
1704
 *                             Default current post.
1705
 * @return false|null|string Link to show comment form, if successful. False, if comments are closed.
1706
 */
1707
function get_post_reply_link($args = array(), $post = null) {
1708
	$defaults = array(
1709
		'add_below'  => 'post',
1710
		'respond_id' => 'respond',
1711
		'reply_text' => __('Leave a Comment'),
1712
		'login_text' => __('Log in to leave a Comment'),
1713
		'before'     => '',
1714
		'after'      => '',
1715
	);
1716
1717
	$args = wp_parse_args($args, $defaults);
1718
1719
	$post = get_post($post);
1720
1721
	if ( ! comments_open( $post->ID ) ) {
1722
		return false;
1723
	}
1724
1725
	if ( get_option('comment_registration') && ! is_user_logged_in() ) {
1726
		$link = sprintf( '<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
1727
			wp_login_url( get_permalink() ),
0 ignored issues
show
It seems like get_permalink() can also be of type false; however, wp_login_url() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1728
			$args['login_text']
1729
		);
1730
	} else {
1731
		$onclick = sprintf( 'return addComment.moveForm( "%1$s-%2$s", "0", "%3$s", "%2$s" )',
1732
			$args['add_below'], $post->ID, $args['respond_id']
1733
		);
1734
1735
		$link = sprintf( "<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s'>%s</a>",
1736
			get_permalink( $post->ID ) . '#' . $args['respond_id'],
1737
			$onclick,
1738
			$args['reply_text']
1739
		);
1740
	}
1741
	$formatted_link = $args['before'] . $link . $args['after'];
1742
1743
	/**
1744
	 * Filters the formatted post comments link HTML.
1745
	 *
1746
	 * @since 2.7.0
1747
	 *
1748
	 * @param string      $formatted The HTML-formatted post comments link.
1749
	 * @param int|WP_Post $post      The post ID or WP_Post object.
1750
	 */
1751
	return apply_filters( 'post_comments_link', $formatted_link, $post );
1752
}
1753
1754
/**
1755
 * Displays the HTML content for reply to post link.
1756
 *
1757
 * @since 2.7.0
1758
 *
1759
 * @see get_post_reply_link()
1760
 *
1761
 * @param array       $args Optional. Override default options,
1762
 * @param int|WP_Post $post Post ID or WP_Post object the comment is going to be displayed on.
1763
 *                          Default current post.
1764
 * @return string|bool|null Link to show comment form, if successful. False, if comments are closed.
1765
 */
1766
function post_reply_link($args = array(), $post = null) {
1767
	echo get_post_reply_link($args, $post);
1768
}
1769
1770
/**
1771
 * Retrieve HTML content for cancel comment reply link.
1772
 *
1773
 * @since 2.7.0
1774
 *
1775
 * @param string $text Optional. Text to display for cancel reply link. Default empty.
1776
 * @return string
1777
 */
1778
function get_cancel_comment_reply_link( $text = '' ) {
1779
	if ( empty($text) )
1780
		$text = __('Click here to cancel reply.');
1781
1782
	$style = isset($_GET['replytocom']) ? '' : ' style="display:none;"';
1783
	$link = esc_html( remove_query_arg('replytocom') ) . '#respond';
0 ignored issues
show
It seems like remove_query_arg('replytocom') targeting remove_query_arg() can also be of type boolean; however, esc_html() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1784
1785
	$formatted_link = '<a rel="nofollow" id="cancel-comment-reply-link" href="' . $link . '"' . $style . '>' . $text . '</a>';
1786
1787
	/**
1788
	 * Filters the cancel comment reply link HTML.
1789
	 *
1790
	 * @since 2.7.0
1791
	 *
1792
	 * @param string $formatted_link The HTML-formatted cancel comment reply link.
1793
	 * @param string $link           Cancel comment reply link URL.
1794
	 * @param string $text           Cancel comment reply link text.
1795
	 */
1796
	return apply_filters( 'cancel_comment_reply_link', $formatted_link, $link, $text );
1797
}
1798
1799
/**
1800
 * Display HTML content for cancel comment reply link.
1801
 *
1802
 * @since 2.7.0
1803
 *
1804
 * @param string $text Optional. Text to display for cancel reply link. Default empty.
1805
 */
1806
function cancel_comment_reply_link( $text = '' ) {
1807
	echo get_cancel_comment_reply_link($text);
1808
}
1809
1810
/**
1811
 * Retrieve hidden input HTML for replying to comments.
1812
 *
1813
 * @since 3.0.0
1814
 *
1815
 * @param int $id Optional. Post ID. Default current post ID.
1816
 * @return string Hidden input HTML for replying to comments
1817
 */
1818
function get_comment_id_fields( $id = 0 ) {
1819
	if ( empty( $id ) )
1820
		$id = get_the_ID();
1821
1822
	$replytoid = isset($_GET['replytocom']) ? (int) $_GET['replytocom'] : 0;
1823
	$result  = "<input type='hidden' name='comment_post_ID' value='$id' id='comment_post_ID' />\n";
1824
	$result .= "<input type='hidden' name='comment_parent' id='comment_parent' value='$replytoid' />\n";
1825
1826
	/**
1827
	 * Filters the returned comment id fields.
1828
	 *
1829
	 * @since 3.0.0
1830
	 *
1831
	 * @param string $result    The HTML-formatted hidden id field comment elements.
1832
	 * @param int    $id        The post ID.
1833
	 * @param int    $replytoid The id of the comment being replied to.
1834
	 */
1835
	return apply_filters( 'comment_id_fields', $result, $id, $replytoid );
1836
}
1837
1838
/**
1839
 * Output hidden input HTML for replying to comments.
1840
 *
1841
 * @since 2.7.0
1842
 *
1843
 * @param int $id Optional. Post ID. Default current post ID.
1844
 */
1845
function comment_id_fields( $id = 0 ) {
1846
	echo get_comment_id_fields( $id );
1847
}
1848
1849
/**
1850
 * Display text based on comment reply status.
1851
 *
1852
 * Only affects users with JavaScript disabled.
1853
 *
1854
 * @internal The $comment global must be present to allow template tags access to the current
1855
 *           comment. See https://core.trac.wordpress.org/changeset/36512.
1856
 *
1857
 * @since 2.7.0
1858
 *
1859
 * @global WP_Comment $comment Current comment.
1860
 *
1861
 * @param string $noreplytext  Optional. Text to display when not replying to a comment.
1862
 *                             Default false.
1863
 * @param string $replytext    Optional. Text to display when replying to a comment.
1864
 *                             Default false. Accepts "%s" for the author of the comment
1865
 *                             being replied to.
1866
 * @param string $linktoparent Optional. Boolean to control making the author's name a link
1867
 *                             to their comment. Default true.
1868
 */
1869
function comment_form_title( $noreplytext = false, $replytext = false, $linktoparent = true ) {
1870
	global $comment;
1871
1872
	if ( false === $noreplytext ) $noreplytext = __( 'Leave a Reply' );
1873
	if ( false === $replytext ) $replytext = __( 'Leave a Reply to %s' );
1874
1875
	$replytoid = isset($_GET['replytocom']) ? (int) $_GET['replytocom'] : 0;
1876
1877
	if ( 0 == $replytoid )
1878
		echo $noreplytext;
1879
	else {
1880
		// Sets the global so that template tags can be used in the comment form.
1881
		$comment = get_comment($replytoid);
1882
		$author = ( $linktoparent ) ? '<a href="#comment-' . get_comment_ID() . '">' . get_comment_author( $comment ) . '</a>' : get_comment_author( $comment );
1883
		printf( $replytext, $author );
1884
	}
1885
}
1886
1887
/**
1888
 * List comments.
1889
 *
1890
 * Used in the comments.php template to list comments for a particular post.
1891
 *
1892
 * @since 2.7.0
1893
 *
1894
 * @see WP_Query->comments
1895
 *
1896
 * @global WP_Query $wp_query
1897
 * @global int      $comment_alt
1898
 * @global int      $comment_depth
1899
 * @global int      $comment_thread_alt
1900
 * @global bool     $overridden_cpage
1901
 * @global bool     $in_comment_loop
1902
 *
1903
 * @param string|array $args {
1904
 *     Optional. Formatting options.
1905
 *
1906
 *     @type object $walker            Instance of a Walker class to list comments. Default null.
1907
 *     @type int    $max_depth         The maximum comments depth. Default empty.
1908
 *     @type string $style             The style of list ordering. Default 'ul'. Accepts 'ul', 'ol'.
1909
 *     @type string $callback          Callback function to use. Default null.
1910
 *     @type string $end-callback      Callback function to use at the end. Default null.
1911
 *     @type string $type              Type of comments to list.
1912
 *                                     Default 'all'. Accepts 'all', 'comment', 'pingback', 'trackback', 'pings'.
1913
 *     @type int    $page              Page ID to list comments for. Default empty.
1914
 *     @type int    $per_page          Number of comments to list per page. Default empty.
1915
 *     @type int    $avatar_size       Height and width dimensions of the avatar size. Default 32.
1916
 *     @type bool   $reverse_top_level Ordering of the listed comments. If true, will display newest comments first.
1917
 *     @type bool   $reverse_children  Whether to reverse child comments in the list. Default null.
1918
 *     @type string $format            How to format the comments list.
1919
 *                                     Default 'html5' if the theme supports it. Accepts 'html5', 'xhtml'.
1920
 *     @type bool   $short_ping        Whether to output short pings. Default false.
1921
 *     @type bool   $echo              Whether to echo the output or return it. Default true.
1922
 * }
1923
 * @param array $comments Optional. Array of WP_Comment objects.
0 ignored issues
show
Should the type for parameter $comments not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1924
 */
1925
function wp_list_comments( $args = array(), $comments = null ) {
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1926
	global $wp_query, $comment_alt, $comment_depth, $comment_thread_alt, $overridden_cpage, $in_comment_loop;
1927
1928
	$in_comment_loop = true;
1929
1930
	$comment_alt = $comment_thread_alt = 0;
1931
	$comment_depth = 1;
1932
1933
	$defaults = array(
1934
		'walker'            => null,
1935
		'max_depth'         => '',
1936
		'style'             => 'ul',
1937
		'callback'          => null,
1938
		'end-callback'      => null,
1939
		'type'              => 'all',
1940
		'page'              => '',
1941
		'per_page'          => '',
1942
		'avatar_size'       => 32,
1943
		'reverse_top_level' => null,
1944
		'reverse_children'  => '',
1945
		'format'            => current_theme_supports( 'html5', 'comment-list' ) ? 'html5' : 'xhtml',
1946
		'short_ping'        => false,
1947
		'echo'              => true,
1948
	);
1949
1950
	$r = wp_parse_args( $args, $defaults );
1951
1952
	/**
1953
	 * Filters the arguments used in retrieving the comment list.
1954
	 *
1955
	 * @since 4.0.0
1956
	 *
1957
	 * @see wp_list_comments()
1958
	 *
1959
	 * @param array $r An array of arguments for displaying comments.
1960
	 */
1961
	$r = apply_filters( 'wp_list_comments_args', $r );
1962
1963
	// Figure out what comments we'll be looping through ($_comments)
1964
	if ( null !== $comments ) {
1965
		$comments = (array) $comments;
1966
		if ( empty($comments) )
1967
			return;
1968 View Code Duplication
		if ( 'all' != $r['type'] ) {
1969
			$comments_by_type = separate_comments($comments);
1970
			if ( empty($comments_by_type[$r['type']]) )
1971
				return;
1972
			$_comments = $comments_by_type[$r['type']];
1973
		} else {
1974
			$_comments = $comments;
1975
		}
1976
	} else {
1977
		/*
1978
		 * If 'page' or 'per_page' has been passed, and does not match what's in $wp_query,
1979
		 * perform a separate comment query and allow Walker_Comment to paginate.
1980
		 */
1981
		if ( $r['page'] || $r['per_page'] ) {
1982
			$current_cpage = get_query_var( 'cpage' );
1983
			if ( ! $current_cpage ) {
1984
				$current_cpage = 'newest' === get_option( 'default_comments_page' ) ? 1 : $wp_query->max_num_comment_pages;
1985
			}
1986
1987
			$current_per_page = get_query_var( 'comments_per_page' );
1988
			if ( $r['page'] != $current_cpage || $r['per_page'] != $current_per_page ) {
1989
				$comment_args = array(
1990
					'post_id' => get_the_ID(),
1991
					'orderby' => 'comment_date_gmt',
1992
					'order' => 'ASC',
1993
					'status' => 'approve',
1994
				);
1995
1996
				if ( is_user_logged_in() ) {
1997
					$comment_args['include_unapproved'] = get_current_user_id();
1998
				} else {
1999
					$commenter = wp_get_current_commenter();
2000
					if ( $commenter['comment_author_email'] ) {
2001
						$comment_args['include_unapproved'] = $commenter['comment_author_email'];
2002
					}
2003
				}
2004
2005
				$comments = get_comments( $comment_args );
2006
2007 View Code Duplication
				if ( 'all' != $r['type'] ) {
2008
					$comments_by_type = separate_comments( $comments );
2009
					if ( empty( $comments_by_type[ $r['type'] ] ) ) {
2010
						return;
2011
					}
2012
2013
					$_comments = $comments_by_type[ $r['type'] ];
2014
				} else {
2015
					$_comments = $comments;
2016
				}
2017
			}
2018
2019
		// Otherwise, fall back on the comments from `$wp_query->comments`.
2020
		} else {
2021
			if ( empty($wp_query->comments) )
2022
				return;
2023
			if ( 'all' != $r['type'] ) {
2024
				if ( empty($wp_query->comments_by_type) )
2025
					$wp_query->comments_by_type = separate_comments($wp_query->comments);
2026
				if ( empty($wp_query->comments_by_type[$r['type']]) )
2027
					return;
2028
				$_comments = $wp_query->comments_by_type[$r['type']];
2029
			} else {
2030
				$_comments = $wp_query->comments;
2031
			}
2032
2033
			if ( $wp_query->max_num_comment_pages ) {
2034
				$default_comments_page = get_option( 'default_comments_page' );
2035
				$cpage = get_query_var( 'cpage' );
2036
				if ( 'newest' === $default_comments_page ) {
2037
					$r['cpage'] = $cpage;
2038
2039
				/*
2040
				 * When first page shows oldest comments, post permalink is the same as
2041
				 * the comment permalink.
2042
				 */
2043
				} elseif ( $cpage == 1 ) {
2044
					$r['cpage'] = '';
2045
				} else {
2046
					$r['cpage'] = $cpage;
2047
				}
2048
2049
				$r['page'] = 0;
2050
				$r['per_page'] = 0;
2051
			}
2052
		}
2053
	}
2054
2055 View Code Duplication
	if ( '' === $r['per_page'] && get_option( 'page_comments' ) ) {
2056
		$r['per_page'] = get_query_var('comments_per_page');
2057
	}
2058
2059
	if ( empty($r['per_page']) ) {
2060
		$r['per_page'] = 0;
2061
		$r['page'] = 0;
2062
	}
2063
2064 View Code Duplication
	if ( '' === $r['max_depth'] ) {
2065
		if ( get_option('thread_comments') )
2066
			$r['max_depth'] = get_option('thread_comments_depth');
2067
		else
2068
			$r['max_depth'] = -1;
2069
	}
2070
2071
	if ( '' === $r['page'] ) {
2072
		if ( empty($overridden_cpage) ) {
2073
			$r['page'] = get_query_var('cpage');
2074
		} else {
2075
			$threaded = ( -1 != $r['max_depth'] );
2076
			$r['page'] = ( 'newest' == get_option('default_comments_page') ) ? get_comment_pages_count($_comments, $r['per_page'], $threaded) : 1;
0 ignored issues
show
The variable $_comments does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2077
			set_query_var( 'cpage', $r['page'] );
2078
		}
2079
	}
2080
	// Validation check
2081
	$r['page'] = intval($r['page']);
2082
	if ( 0 == $r['page'] && 0 != $r['per_page'] )
2083
		$r['page'] = 1;
2084
2085
	if ( null === $r['reverse_top_level'] )
2086
		$r['reverse_top_level'] = ( 'desc' == get_option('comment_order') );
2087
2088
	wp_queue_comments_for_comment_meta_lazyload( $_comments );
2089
2090
	if ( empty( $r['walker'] ) ) {
2091
		$walker = new Walker_Comment;
2092
	} else {
2093
		$walker = $r['walker'];
2094
	}
2095
2096
	$output = $walker->paged_walk( $_comments, $r['max_depth'], $r['page'], $r['per_page'], $r );
2097
2098
	$in_comment_loop = false;
2099
2100
	if ( $r['echo'] ) {
2101
		echo $output;
2102
	} else {
2103
		return $output;
2104
	}
2105
}
2106
2107
/**
2108
 * Outputs a complete commenting form for use within a template.
2109
 *
2110
 * Most strings and form fields may be controlled through the $args array passed
2111
 * into the function, while you may also choose to use the {@see 'comment_form_default_fields'}
2112
 * filter to modify the array of default fields if you'd just like to add a new
2113
 * one or remove a single field. All fields are also individually passed through
2114
 * a filter of the {@see 'comment_form_field_$name'} where $name is the key used
2115
 * in the array of fields.
2116
 *
2117
 * @since 3.0.0
2118
 * @since 4.1.0 Introduced the 'class_submit' argument.
2119
 * @since 4.2.0 Introduced the 'submit_button' and 'submit_fields' arguments.
2120
 * @since 4.4.0 Introduced the 'class_form', 'title_reply_before', 'title_reply_after',
2121
 *              'cancel_reply_before', and 'cancel_reply_after' arguments.
2122
 * @since 4.5.0 The 'author', 'email', and 'url' form fields are limited to 245, 100,
2123
 *              and 200 characters, respectively.
2124
 * @since 4.6.0 Introduced the 'action' argument.
2125
 *
2126
 * @param array       $args {
2127
 *     Optional. Default arguments and form fields to override.
2128
 *
2129
 *     @type array $fields {
2130
 *         Default comment fields, filterable by default via the {@see 'comment_form_default_fields'} hook.
2131
 *
2132
 *         @type string $author Comment author field HTML.
2133
 *         @type string $email  Comment author email field HTML.
2134
 *         @type string $url    Comment author URL field HTML.
2135
 *     }
2136
 *     @type string $comment_field        The comment textarea field HTML.
2137
 *     @type string $must_log_in          HTML element for a 'must be logged in to comment' message.
2138
 *     @type string $logged_in_as         HTML element for a 'logged in as [user]' message.
2139
 *     @type string $comment_notes_before HTML element for a message displayed before the comment fields
2140
 *                                        if the user is not logged in.
2141
 *                                        Default 'Your email address will not be published.'.
2142
 *     @type string $comment_notes_after  HTML element for a message displayed after the textarea field.
2143
 *     @type string $action               The comment form element action attribute. Default '/wp-comments-post.php'.
2144
 *     @type string $id_form              The comment form element id attribute. Default 'commentform'.
2145
 *     @type string $id_submit            The comment submit element id attribute. Default 'submit'.
2146
 *     @type string $class_form           The comment form element class attribute. Default 'comment-form'.
2147
 *     @type string $class_submit         The comment submit element class attribute. Default 'submit'.
2148
 *     @type string $name_submit          The comment submit element name attribute. Default 'submit'.
2149
 *     @type string $title_reply          The translatable 'reply' button label. Default 'Leave a Reply'.
2150
 *     @type string $title_reply_to       The translatable 'reply-to' button label. Default 'Leave a Reply to %s',
2151
 *                                        where %s is the author of the comment being replied to.
2152
 *     @type string $title_reply_before   HTML displayed before the comment form title.
2153
 *                                        Default: '<h3 id="reply-title" class="comment-reply-title">'.
2154
 *     @type string $title_reply_after    HTML displayed after the comment form title.
2155
 *                                        Default: '</h3>'.
2156
 *     @type string $cancel_reply_before  HTML displayed before the cancel reply link.
2157
 *     @type string $cancel_reply_after   HTML displayed after the cancel reply link.
2158
 *     @type string $cancel_reply_link    The translatable 'cancel reply' button label. Default 'Cancel reply'.
2159
 *     @type string $label_submit         The translatable 'submit' button label. Default 'Post a comment'.
2160
 *     @type string $submit_button        HTML format for the Submit button.
2161
 *                                        Default: '<input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" />'.
2162
 *     @type string $submit_field         HTML format for the markup surrounding the Submit button and comment hidden
2163
 *                                        fields. Default: '<p class="form-submit">%1$s %2$s</p>', where %1$s is the
2164
 *                                        submit button markup and %2$s is the comment hidden fields.
2165
 *     @type string $format               The comment form format. Default 'xhtml'. Accepts 'xhtml', 'html5'.
2166
 * }
2167
 * @param int|WP_Post $post_id Post ID or WP_Post object to generate the form for. Default current post.
2168
 */
2169
function comment_form( $args = array(), $post_id = null ) {
2170
	if ( null === $post_id )
2171
		$post_id = get_the_ID();
2172
2173
	// Exit the function when comments for the post are closed.
2174
	if ( ! comments_open( $post_id ) ) {
2175
		/**
2176
		 * Fires after the comment form if comments are closed.
2177
		 *
2178
		 * @since 3.0.0
2179
		 */
2180
		do_action( 'comment_form_comments_closed' );
2181
2182
		return;
2183
	}
2184
2185
	$commenter = wp_get_current_commenter();
2186
	$user = wp_get_current_user();
2187
	$user_identity = $user->exists() ? $user->display_name : '';
2188
2189
	$args = wp_parse_args( $args );
2190
	if ( ! isset( $args['format'] ) )
2191
		$args['format'] = current_theme_supports( 'html5', 'comment-form' ) ? 'html5' : 'xhtml';
2192
2193
	$req      = get_option( 'require_name_email' );
2194
	$aria_req = ( $req ? " aria-required='true'" : '' );
2195
	$html_req = ( $req ? " required='required'" : '' );
2196
	$html5    = 'html5' === $args['format'];
2197
	$fields   =  array(
2198
		'author' => '<p class="comment-form-author">' . '<label for="author">' . __( 'Name' ) . ( $req ? ' <span class="required">*</span>' : '' ) . '</label> ' .
2199
		            '<input id="author" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30" maxlength="245"' . $aria_req . $html_req . ' /></p>',
2200
		'email'  => '<p class="comment-form-email"><label for="email">' . __( 'Email' ) . ( $req ? ' <span class="required">*</span>' : '' ) . '</label> ' .
2201
		            '<input id="email" name="email" ' . ( $html5 ? 'type="email"' : 'type="text"' ) . ' value="' . esc_attr(  $commenter['comment_author_email'] ) . '" size="30" maxlength="100" aria-describedby="email-notes"' . $aria_req . $html_req  . ' /></p>',
2202
		'url'    => '<p class="comment-form-url"><label for="url">' . __( 'Website' ) . '</label> ' .
2203
		            '<input id="url" name="url" ' . ( $html5 ? 'type="url"' : 'type="text"' ) . ' value="' . esc_attr( $commenter['comment_author_url'] ) . '" size="30" maxlength="200" /></p>',
2204
	);
2205
2206
	$required_text = sprintf( ' ' . __('Required fields are marked %s'), '<span class="required">*</span>' );
2207
2208
	/**
2209
	 * Filters the default comment form fields.
2210
	 *
2211
	 * @since 3.0.0
2212
	 *
2213
	 * @param array $fields The default comment fields.
2214
	 */
2215
	$fields = apply_filters( 'comment_form_default_fields', $fields );
2216
	$defaults = array(
2217
		'fields'               => $fields,
2218
		'comment_field'        => '<p class="comment-form-comment"><label for="comment">' . _x( 'Comment', 'noun' ) . '</label> <textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" aria-required="true" required="required"></textarea></p>',
2219
		/** This filter is documented in wp-includes/link-template.php */
2220
		'must_log_in'          => '<p class="must-log-in">' . sprintf(
2221
		                              /* translators: %s: login URL */
2222
		                              __( 'You must be <a href="%s">logged in</a> to post a comment.' ),
2223
		                              wp_login_url( apply_filters( 'the_permalink', get_permalink( $post_id ) ) )
2224
		                          ) . '</p>',
2225
		/** This filter is documented in wp-includes/link-template.php */
2226
		'logged_in_as'         => '<p class="logged-in-as">' . sprintf(
2227
		                              /* translators: 1: edit user link, 2: accessibility text, 3: user name, 4: logout URL */
2228
		                              __( '<a href="%1$s" aria-label="%2$s">Logged in as %3$s</a>. <a href="%4$s">Log out?</a>' ),
2229
		                              get_edit_user_link(),
2230
		                              /* translators: %s: user name */
2231
		                              esc_attr( sprintf( __( 'Logged in as %s. Edit your profile.' ), $user_identity ) ),
2232
		                              $user_identity,
2233
		                              wp_logout_url( apply_filters( 'the_permalink', get_permalink( $post_id ) ) )
2234
		                          ) . '</p>',
2235
		'comment_notes_before' => '<p class="comment-notes"><span id="email-notes">' . __( 'Your email address will not be published.' ) . '</span>'. ( $req ? $required_text : '' ) . '</p>',
2236
		'comment_notes_after'  => '',
2237
		'action'               => site_url( '/wp-comments-post.php' ),
2238
		'id_form'              => 'commentform',
2239
		'id_submit'            => 'submit',
2240
		'class_form'           => 'comment-form',
2241
		'class_submit'         => 'submit',
2242
		'name_submit'          => 'submit',
2243
		'title_reply'          => __( 'Leave a Reply' ),
2244
		'title_reply_to'       => __( 'Leave a Reply to %s' ),
2245
		'title_reply_before'   => '<h3 id="reply-title" class="comment-reply-title">',
2246
		'title_reply_after'    => '</h3>',
2247
		'cancel_reply_before'  => ' <small>',
2248
		'cancel_reply_after'   => '</small>',
2249
		'cancel_reply_link'    => __( 'Cancel reply' ),
2250
		'label_submit'         => __( 'Post Comment' ),
2251
		'submit_button'        => '<input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" />',
2252
		'submit_field'         => '<p class="form-submit">%1$s %2$s</p>',
2253
		'format'               => 'xhtml',
2254
	);
2255
2256
	/**
2257
	 * Filters the comment form default arguments.
2258
	 *
2259
	 * Use {@see 'comment_form_default_fields'} to filter the comment fields.
2260
	 *
2261
	 * @since 3.0.0
2262
	 *
2263
	 * @param array $defaults The default comment form arguments.
2264
	 */
2265
	$args = wp_parse_args( $args, apply_filters( 'comment_form_defaults', $defaults ) );
2266
2267
	// Ensure that the filtered args contain all required default values.
2268
	$args = array_merge( $defaults, $args );
2269
2270
	/**
2271
	 * Fires before the comment form.
2272
	 *
2273
	 * @since 3.0.0
2274
	 */
2275
	do_action( 'comment_form_before' );
2276
	?>
2277
	<div id="respond" class="comment-respond">
2278
		<?php
2279
		echo $args['title_reply_before'];
2280
2281
		comment_form_title( $args['title_reply'], $args['title_reply_to'] );
2282
2283
		echo $args['cancel_reply_before'];
2284
2285
		cancel_comment_reply_link( $args['cancel_reply_link'] );
2286
2287
		echo $args['cancel_reply_after'];
2288
2289
		echo $args['title_reply_after'];
2290
2291
		if ( get_option( 'comment_registration' ) && !is_user_logged_in() ) :
2292
			echo $args['must_log_in'];
2293
			/**
2294
			 * Fires after the HTML-formatted 'must log in after' message in the comment form.
2295
			 *
2296
			 * @since 3.0.0
2297
			 */
2298
			do_action( 'comment_form_must_log_in_after' );
2299
		else : ?>
2300
			<form action="<?php echo esc_url( $args['action'] ); ?>" method="post" id="<?php echo esc_attr( $args['id_form'] ); ?>" class="<?php echo esc_attr( $args['class_form'] ); ?>"<?php echo $html5 ? ' novalidate' : ''; ?>>
2301
				<?php
2302
				/**
2303
				 * Fires at the top of the comment form, inside the form tag.
2304
				 *
2305
				 * @since 3.0.0
2306
				 */
2307
				do_action( 'comment_form_top' );
2308
2309
				if ( is_user_logged_in() ) :
2310
					/**
2311
					 * Filters the 'logged in' message for the comment form for display.
2312
					 *
2313
					 * @since 3.0.0
2314
					 *
2315
					 * @param string $args_logged_in The logged-in-as HTML-formatted message.
2316
					 * @param array  $commenter      An array containing the comment author's
2317
					 *                               username, email, and URL.
2318
					 * @param string $user_identity  If the commenter is a registered user,
2319
					 *                               the display name, blank otherwise.
2320
					 */
2321
					echo apply_filters( 'comment_form_logged_in', $args['logged_in_as'], $commenter, $user_identity );
2322
2323
					/**
2324
					 * Fires after the is_user_logged_in() check in the comment form.
2325
					 *
2326
					 * @since 3.0.0
2327
					 *
2328
					 * @param array  $commenter     An array containing the comment author's
2329
					 *                              username, email, and URL.
2330
					 * @param string $user_identity If the commenter is a registered user,
2331
					 *                              the display name, blank otherwise.
2332
					 */
2333
					do_action( 'comment_form_logged_in_after', $commenter, $user_identity );
2334
2335
				else :
2336
2337
					echo $args['comment_notes_before'];
2338
2339
				endif;
2340
2341
				// Prepare an array of all fields, including the textarea
2342
				$comment_fields = array( 'comment' => $args['comment_field'] ) + (array) $args['fields'];
2343
2344
				/**
2345
				 * Filters the comment form fields, including the textarea.
2346
				 *
2347
				 * @since 4.4.0
2348
				 *
2349
				 * @param array $comment_fields The comment fields.
2350
				 */
2351
				$comment_fields = apply_filters( 'comment_form_fields', $comment_fields );
2352
2353
				// Get an array of field names, excluding the textarea
2354
				$comment_field_keys = array_diff( array_keys( $comment_fields ), array( 'comment' ) );
2355
2356
				// Get the first and the last field name, excluding the textarea
2357
				$first_field = reset( $comment_field_keys );
2358
				$last_field  = end( $comment_field_keys );
2359
2360
				foreach ( $comment_fields as $name => $field ) {
2361
2362
					if ( 'comment' === $name ) {
2363
2364
						/**
2365
						 * Filters the content of the comment textarea field for display.
2366
						 *
2367
						 * @since 3.0.0
2368
						 *
2369
						 * @param string $args_comment_field The content of the comment textarea field.
2370
						 */
2371
						echo apply_filters( 'comment_form_field_comment', $field );
2372
2373
						echo $args['comment_notes_after'];
2374
2375
					} elseif ( ! is_user_logged_in() ) {
2376
2377
						if ( $first_field === $name ) {
2378
							/**
2379
							 * Fires before the comment fields in the comment form, excluding the textarea.
2380
							 *
2381
							 * @since 3.0.0
2382
							 */
2383
							do_action( 'comment_form_before_fields' );
2384
						}
2385
2386
						/**
2387
						 * Filters a comment form field for display.
2388
						 *
2389
						 * The dynamic portion of the filter hook, `$name`, refers to the name
2390
						 * of the comment form field. Such as 'author', 'email', or 'url'.
2391
						 *
2392
						 * @since 3.0.0
2393
						 *
2394
						 * @param string $field The HTML-formatted output of the comment form field.
2395
						 */
2396
						echo apply_filters( "comment_form_field_{$name}", $field ) . "\n";
2397
2398
						if ( $last_field === $name ) {
2399
							/**
2400
							 * Fires after the comment fields in the comment form, excluding the textarea.
2401
							 *
2402
							 * @since 3.0.0
2403
							 */
2404
							do_action( 'comment_form_after_fields' );
2405
						}
2406
					}
2407
				}
2408
2409
				$submit_button = sprintf(
2410
					$args['submit_button'],
2411
					esc_attr( $args['name_submit'] ),
2412
					esc_attr( $args['id_submit'] ),
2413
					esc_attr( $args['class_submit'] ),
2414
					esc_attr( $args['label_submit'] )
2415
				);
2416
2417
				/**
2418
				 * Filters the submit button for the comment form to display.
2419
				 *
2420
				 * @since 4.2.0
2421
				 *
2422
				 * @param string $submit_button HTML markup for the submit button.
2423
				 * @param array  $args          Arguments passed to `comment_form()`.
2424
				 */
2425
				$submit_button = apply_filters( 'comment_form_submit_button', $submit_button, $args );
2426
2427
				$submit_field = sprintf(
2428
					$args['submit_field'],
2429
					$submit_button,
2430
					get_comment_id_fields( $post_id )
2431
				);
2432
2433
				/**
2434
				 * Filters the submit field for the comment form to display.
2435
				 *
2436
				 * The submit field includes the submit button, hidden fields for the
2437
				 * comment form, and any wrapper markup.
2438
				 *
2439
				 * @since 4.2.0
2440
				 *
2441
				 * @param string $submit_field HTML markup for the submit field.
2442
				 * @param array  $args         Arguments passed to comment_form().
2443
				 */
2444
				echo apply_filters( 'comment_form_submit_field', $submit_field, $args );
2445
2446
				/**
2447
				 * Fires at the bottom of the comment form, inside the closing </form> tag.
2448
				 *
2449
				 * @since 1.5.0
2450
				 *
2451
				 * @param int $post_id The post ID.
2452
				 */
2453
				do_action( 'comment_form', $post_id );
2454
				?>
2455
			</form>
2456
		<?php endif; ?>
2457
	</div><!-- #respond -->
2458
	<?php
2459
2460
	/**
2461
	 * Fires after the comment form.
2462
	 *
2463
	 * @since 3.0.0
2464
	 */
2465
	do_action( 'comment_form_after' );
2466
}
2467