Issues (2010)

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.

wp-includes/comment-template.php (12 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

Code
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 $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.
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
function comments_open( $post_id = null ) {
1191
1192
	$_post = get_post($post_id);
1193
1194
	$open = ( 'open' == $_post->comment_status );
1195
1196
	/**
1197
	 * Filters whether the current post is open for comments.
1198
	 *
1199
	 * @since 2.5.0
1200
	 *
1201
	 * @param bool        $open    Whether the current post is open for comments.
1202
	 * @param int|WP_Post $post_id The post ID or WP_Post object.
1203
	 */
1204
	return apply_filters( 'comments_open', $open, $post_id );
1205
}
1206
1207
/**
1208
 * Whether the current post is open for pings.
1209
 *
1210
 * @since 1.5.0
1211
 *
1212
 * @param int|WP_Post $post_id Post ID or WP_Post object. Default current post.
1213
 * @return bool True if pings are accepted
1214
 */
1215
function pings_open( $post_id = null ) {
1216
1217
	$_post = get_post($post_id);
1218
1219
	$open = ( 'open' == $_post->ping_status );
1220
1221
	/**
1222
	 * Filters whether the current post is open for pings.
1223
	 *
1224
	 * @since 2.5.0
1225
	 *
1226
	 * @param bool        $open    Whether the current post is open for pings.
1227
	 * @param int|WP_Post $post_id The post ID or WP_Post object.
1228
	 */
1229
	return apply_filters( 'pings_open', $open, $post_id );
1230
}
1231
1232
/**
1233
 * Display form token for unfiltered comments.
1234
 *
1235
 * Will only display nonce token if the current user has permissions for
1236
 * unfiltered html. Won't display the token for other users.
1237
 *
1238
 * The function was backported to 2.0.10 and was added to versions 2.1.3 and
1239
 * above. Does not exist in versions prior to 2.0.10 in the 2.0 branch and in
1240
 * the 2.1 branch, prior to 2.1.3. Technically added in 2.2.0.
1241
 *
1242
 * Backported to 2.0.10.
1243
 *
1244
 * @since 2.1.3
1245
 */
1246
function wp_comment_form_unfiltered_html_nonce() {
1247
	$post = get_post();
1248
	$post_id = $post ? $post->ID : 0;
1249
1250
	if ( current_user_can( 'unfiltered_html' ) ) {
1251
		wp_nonce_field( 'unfiltered-html-comment_' . $post_id, '_wp_unfiltered_html_comment_disabled', false );
1252
		echo "<script>(function(){if(window===window.parent){document.getElementById('_wp_unfiltered_html_comment_disabled').name='_wp_unfiltered_html_comment';}})();</script>\n";
1253
	}
1254
}
1255
1256
/**
1257
 * Load the comment template specified in $file.
1258
 *
1259
 * Will not display the comments template if not on single post or page, or if
1260
 * the post does not have comments.
1261
 *
1262
 * Uses the WordPress database object to query for the comments. The comments
1263
 * are passed through the {@see 'comments_array'} filter hook with the list of comments
1264
 * and the post ID respectively.
1265
 *
1266
 * The `$file` path is passed through a filter hook called {@see 'comments_template'},
1267
 * which includes the TEMPLATEPATH and $file combined. Tries the $filtered path
1268
 * first and if it fails it will require the default comment template from the
1269
 * default theme. If either does not exist, then the WordPress process will be
1270
 * halted. It is advised for that reason, that the default theme is not deleted.
1271
 *
1272
 * Will not try to get the comments if the post has none.
1273
 *
1274
 * @since 1.5.0
1275
 *
1276
 * @global WP_Query   $wp_query
1277
 * @global WP_Post    $post
1278
 * @global wpdb       $wpdb
1279
 * @global int        $id
1280
 * @global WP_Comment $comment
1281
 * @global string     $user_login
1282
 * @global int        $user_ID
1283
 * @global string     $user_identity
1284
 * @global bool       $overridden_cpage
1285
 * @global bool       $withcomments
1286
 *
1287
 * @param string $file              Optional. The file to load. Default '/comments.php'.
1288
 * @param bool   $separate_comments Optional. Whether to separate the comments by comment type.
1289
 *                                  Default false.
1290
 */
1291
function comments_template( $file = '/comments.php', $separate_comments = false ) {
1292
	global $wp_query, $withcomments, $post, $wpdb, $id, $comment, $user_login, $user_ID, $user_identity, $overridden_cpage;
1293
1294
	if ( !(is_single() || is_page() || $withcomments) || empty($post) )
1295
		return;
1296
1297
	if ( empty($file) )
1298
		$file = '/comments.php';
1299
1300
	$req = get_option('require_name_email');
1301
1302
	/*
1303
	 * Comment author information fetched from the comment cookies.
1304
	 */
1305
	$commenter = wp_get_current_commenter();
1306
1307
	/*
1308
	 * The name of the current comment author escaped for use in attributes.
1309
	 * Escaped by sanitize_comment_cookies().
1310
	 */
1311
	$comment_author = $commenter['comment_author'];
1312
1313
	/*
1314
	 * The email address of the current comment author escaped for use in attributes.
1315
	 * Escaped by sanitize_comment_cookies().
1316
	 */
1317
	$comment_author_email = $commenter['comment_author_email'];
1318
1319
	/*
1320
	 * The url of the current comment author escaped for use in attributes.
1321
	 */
1322
	$comment_author_url = esc_url($commenter['comment_author_url']);
1323
1324
	$comment_args = array(
1325
		'orderby' => 'comment_date_gmt',
1326
		'order' => 'ASC',
1327
		'status'  => 'approve',
1328
		'post_id' => $post->ID,
1329
		'no_found_rows' => false,
1330
		'update_comment_meta_cache' => false, // We lazy-load comment meta for performance.
1331
	);
1332
1333
	if ( get_option('thread_comments') ) {
1334
		$comment_args['hierarchical'] = 'threaded';
1335
	} else {
1336
		$comment_args['hierarchical'] = false;
1337
	}
1338
1339
	if ( $user_ID ) {
1340
		$comment_args['include_unapproved'] = array( $user_ID );
1341
	} elseif ( ! empty( $comment_author_email ) ) {
1342
		$comment_args['include_unapproved'] = array( $comment_author_email );
1343
	}
1344
1345
	$per_page = 0;
1346
	if ( get_option( 'page_comments' ) ) {
1347
		$per_page = (int) get_query_var( 'comments_per_page' );
1348
		if ( 0 === $per_page ) {
1349
			$per_page = (int) get_option( 'comments_per_page' );
1350
		}
1351
1352
		$comment_args['number'] = $per_page;
1353
		$page = (int) get_query_var( 'cpage' );
1354
1355
		if ( $page ) {
1356
			$comment_args['offset'] = ( $page - 1 ) * $per_page;
1357
		} elseif ( 'oldest' === get_option( 'default_comments_page' ) ) {
1358
			$comment_args['offset'] = 0;
1359
		} else {
1360
			// If fetching the first page of 'newest', we need a top-level comment count.
1361
			$top_level_query = new WP_Comment_Query();
1362
			$top_level_args  = array(
1363
				'count'   => true,
1364
				'orderby' => false,
1365
				'post_id' => $post->ID,
1366
				'status'  => 'approve',
1367
			);
1368
1369
			if ( $comment_args['hierarchical'] ) {
1370
				$top_level_args['parent'] = 0;
1371
			}
1372
1373
			if ( isset( $comment_args['include_unapproved'] ) ) {
1374
				$top_level_args['include_unapproved'] = $comment_args['include_unapproved'];
1375
			}
1376
1377
			$top_level_count = $top_level_query->query( $top_level_args );
1378
1379
			$comment_args['offset'] = ( ceil( $top_level_count / $per_page ) - 1 ) * $per_page;
1380
		}
1381
	}
1382
1383
	/**
1384
	 * Filters the arguments used to query comments in comments_template().
1385
	 *
1386
	 * @since 4.5.0
1387
	 *
1388
	 * @see WP_Comment_Query::__construct()
1389
	 *
1390
	 * @param array $comment_args {
1391
	 *     Array of WP_Comment_Query arguments.
1392
	 *
1393
	 *     @type string|array $orderby                   Field(s) to order by.
1394
	 *     @type string       $order                     Order of results. Accepts 'ASC' or 'DESC'.
1395
	 *     @type string       $status                    Comment status.
1396
	 *     @type array        $include_unapproved        Array of IDs or email addresses whose unapproved comments
1397
	 *                                                   will be included in results.
1398
	 *     @type int          $post_id                   ID of the post.
1399
	 *     @type bool         $no_found_rows             Whether to refrain from querying for found rows.
1400
	 *     @type bool         $update_comment_meta_cache Whether to prime cache for comment meta.
1401
	 *     @type bool|string  $hierarchical              Whether to query for comments hierarchically.
1402
	 *     @type int          $offset                    Comment offset.
1403
	 *     @type int          $number                    Number of comments to fetch.
1404
	 * }
1405
	 */
1406
	$comment_args = apply_filters( 'comments_template_query_args', $comment_args );
1407
	$comment_query = new WP_Comment_Query( $comment_args );
1408
	$_comments = $comment_query->comments;
1409
1410
	// Trees must be flattened before they're passed to the walker.
1411
	if ( $comment_args['hierarchical'] ) {
1412
		$comments_flat = array();
1413
		foreach ( $_comments as $_comment ) {
1414
			$comments_flat[]  = $_comment;
1415
			$comment_children = $_comment->get_children( array(
1416
				'format' => 'flat',
1417
				'status' => $comment_args['status'],
1418
				'orderby' => $comment_args['orderby']
1419
			) );
1420
1421
			foreach ( $comment_children as $comment_child ) {
1422
				$comments_flat[] = $comment_child;
1423
			}
1424
		}
1425
	} else {
1426
		$comments_flat = $_comments;
1427
	}
1428
1429
	/**
1430
	 * Filters the comments array.
1431
	 *
1432
	 * @since 2.1.0
1433
	 *
1434
	 * @param array $comments Array of comments supplied to the comments template.
1435
	 * @param int   $post_ID  Post ID.
1436
	 */
1437
	$wp_query->comments = apply_filters( 'comments_array', $comments_flat, $post->ID );
1438
1439
	$comments = &$wp_query->comments;
1440
	$wp_query->comment_count = count($wp_query->comments);
1441
	$wp_query->max_num_comment_pages = $comment_query->max_num_pages;
1442
1443
	if ( $separate_comments ) {
1444
		$wp_query->comments_by_type = separate_comments($comments);
1445
		$comments_by_type = &$wp_query->comments_by_type;
1446
	} else {
1447
		$wp_query->comments_by_type = array();
1448
	}
1449
1450
	$overridden_cpage = false;
1451
	if ( '' == get_query_var( 'cpage' ) && $wp_query->max_num_comment_pages > 1 ) {
1452
		set_query_var( 'cpage', 'newest' == get_option('default_comments_page') ? get_comment_pages_count() : 1 );
1453
		$overridden_cpage = true;
1454
	}
1455
1456
	if ( !defined('COMMENTS_TEMPLATE') )
1457
		define('COMMENTS_TEMPLATE', true);
1458
1459
	$theme_template = STYLESHEETPATH . $file;
1460
	/**
1461
	 * Filters the path to the theme template file used for the comments template.
1462
	 *
1463
	 * @since 1.5.1
1464
	 *
1465
	 * @param string $theme_template The path to the theme template file.
1466
	 */
1467
	$include = apply_filters( 'comments_template', $theme_template );
1468
	if ( file_exists( $include ) )
1469
		require( $include );
1470
	elseif ( file_exists( TEMPLATEPATH . $file ) )
1471
		require( TEMPLATEPATH . $file );
1472
	else // Backward compat code will be removed in a future release
1473
		require( ABSPATH . WPINC . '/theme-compat/comments.php');
1474
}
1475
1476
/**
1477
 * Displays the link to the comments for the current post ID.
1478
 *
1479
 * @since 0.71
1480
 *
1481
 * @param string $zero      Optional. String to display when no comments. Default false.
1482
 * @param string $one       Optional. String to display when only one comment is available.
1483
 *                          Default false.
1484
 * @param string $more      Optional. String to display when there are more than one comment.
1485
 *                          Default false.
1486
 * @param string $css_class Optional. CSS class to use for comments. Default empty.
1487
 * @param string $none      Optional. String to display when comments have been turned off.
1488
 *                          Default false.
1489
 */
1490
function comments_popup_link( $zero = false, $one = false, $more = false, $css_class = '', $none = false ) {
1491
	$id = get_the_ID();
1492
	$title = get_the_title();
1493
	$number = get_comments_number( $id );
0 ignored issues
show
It seems like $id defined by get_the_ID() on line 1491 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...
1494
1495
	if ( false === $zero ) {
1496
		/* translators: %s: post title */
1497
		$zero = sprintf( __( 'No Comments<span class="screen-reader-text"> on %s</span>' ), $title );
1498
	}
1499
1500
	if ( false === $one ) {
1501
		/* translators: %s: post title */
1502
		$one = sprintf( __( '1 Comment<span class="screen-reader-text"> on %s</span>' ), $title );
1503
	}
1504
1505
	if ( false === $more ) {
1506
		/* translators: 1: Number of comments 2: post title */
1507
		$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 );
1508
		$more = sprintf( $more, number_format_i18n( $number ), $title );
1509
	}
1510
1511
	if ( false === $none ) {
1512
		/* translators: %s: post title */
1513
		$none = sprintf( __( 'Comments Off<span class="screen-reader-text"> on %s</span>' ), $title );
1514
	}
1515
1516
	if ( 0 == $number && !comments_open() && !pings_open() ) {
1517
		echo '<span' . ((!empty($css_class)) ? ' class="' . esc_attr( $css_class ) . '"' : '') . '>' . $none . '</span>';
1518
		return;
1519
	}
1520
1521
	if ( post_password_required() ) {
1522
		_e( 'Enter your password to view comments.' );
1523
		return;
1524
	}
1525
1526
	echo '<a href="';
1527
	if ( 0 == $number ) {
1528
		$respond_link = get_permalink() . '#respond';
1529
		/**
1530
		 * Filters the respond link when a post has no comments.
1531
		 *
1532
		 * @since 4.4.0
1533
		 *
1534
		 * @param string $respond_link The default response link.
1535
		 * @param integer $id The post ID.
1536
		 */
1537
		echo apply_filters( 'respond_link', $respond_link, $id );
1538
	} else {
1539
		comments_link();
1540
	}
1541
	echo '"';
1542
1543
	if ( !empty( $css_class ) ) {
1544
		echo ' class="'.$css_class.'" ';
1545
	}
1546
1547
	$attributes = '';
1548
	/**
1549
	 * Filters the comments link attributes for display.
1550
	 *
1551
	 * @since 2.5.0
1552
	 *
1553
	 * @param string $attributes The comments link attributes. Default empty.
1554
	 */
1555
	echo apply_filters( 'comments_popup_link_attributes', $attributes );
1556
1557
	echo '>';
1558
	comments_number( $zero, $one, $more );
1559
	echo '</a>';
1560
}
1561
1562
/**
1563
 * Retrieve HTML content for reply to comment link.
1564
 *
1565
 * @since 2.7.0
1566
 * @since 4.4.0 Added the ability for `$comment` to also accept a WP_Comment object.
1567
 *
1568
 * @param array $args {
1569
 *     Optional. Override default arguments.
1570
 *
1571
 *     @type string $add_below  The first part of the selector used to identify the comment to respond below.
1572
 *                              The resulting value is passed as the first parameter to addComment.moveForm(),
1573
 *                              concatenated as $add_below-$comment->comment_ID. Default 'comment'.
1574
 *     @type string $respond_id The selector identifying the responding comment. Passed as the third parameter
1575
 *                              to addComment.moveForm(), and appended to the link URL as a hash value.
1576
 *                              Default 'respond'.
1577
 *     @type string $reply_text The text of the Reply link. Default 'Reply'.
1578
 *     @type string $login_text The text of the link to reply if logged out. Default 'Log in to Reply'.
1579
 *     @type int    $depth'     The depth of the new comment. Must be greater than 0 and less than the value
1580
 *                              of the 'thread_comments_depth' option set in Settings > Discussion. Default 0.
1581
 *     @type string $before     The text or HTML to add before the reply link. Default empty.
1582
 *     @type string $after      The text or HTML to add after the reply link. Default empty.
1583
 * }
1584
 * @param int|WP_Comment $comment Comment being replied to. Default current comment.
1585
 * @param int|WP_Post    $post    Post ID or WP_Post object the comment is going to be displayed on.
1586
 *                                Default current post.
1587
 * @return void|false|string Link to show comment form, if successful. False, if comments are closed.
1588
 */
1589
function get_comment_reply_link( $args = array(), $comment = null, $post = null ) {
1590
	$defaults = array(
1591
		'add_below'     => 'comment',
1592
		'respond_id'    => 'respond',
1593
		'reply_text'    => __( 'Reply' ),
1594
		'reply_to_text' => __( 'Reply to %s' ),
1595
		'login_text'    => __( 'Log in to Reply' ),
1596
		'depth'         => 0,
1597
		'before'        => '',
1598
		'after'         => ''
1599
	);
1600
1601
	$args = wp_parse_args( $args, $defaults );
1602
1603
	if ( 0 == $args['depth'] || $args['max_depth'] <= $args['depth'] ) {
1604
		return;
1605
	}
1606
1607
	$comment = get_comment( $comment );
1608
1609
	if ( empty( $post ) ) {
1610
		$post = $comment->comment_post_ID;
1611
	}
1612
1613
	$post = get_post( $post );
1614
1615
	if ( ! comments_open( $post->ID ) ) {
1616
		return false;
1617
	}
1618
1619
	/**
1620
	 * Filters the comment reply link arguments.
1621
	 *
1622
	 * @since 4.1.0
1623
	 *
1624
	 * @param array      $args    Comment reply link arguments. See get_comment_reply_link()
1625
	 *                            for more information on accepted arguments.
1626
	 * @param WP_Comment $comment The object of the comment being replied to.
1627
	 * @param WP_Post    $post    The WP_Post object.
1628
	 */
1629
	$args = apply_filters( 'comment_reply_link_args', $args, $comment, $post );
1630
1631
	if ( get_option( 'comment_registration' ) && ! is_user_logged_in() ) {
1632
		$link = sprintf( '<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
1633
			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...
1634
			$args['login_text']
1635
		);
1636
	} else {
1637
		$onclick = sprintf( 'return addComment.moveForm( "%1$s-%2$s", "%2$s", "%3$s", "%4$s" )',
1638
			$args['add_below'], $comment->comment_ID, $args['respond_id'], $post->ID
1639
		);
1640
1641
		$link = sprintf( "<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s' aria-label='%s'>%s</a>",
1642
			esc_url( add_query_arg( 'replytocom', $comment->comment_ID, get_permalink( $post->ID ) ) ) . "#" . $args['respond_id'],
1643
			$onclick,
1644
			esc_attr( sprintf( $args['reply_to_text'], $comment->comment_author ) ),
1645
			$args['reply_text']
1646
		);
1647
	}
1648
1649
	/**
1650
	 * Filters the comment reply link.
1651
	 *
1652
	 * @since 2.7.0
1653
	 *
1654
	 * @param string  $link    The HTML markup for the comment reply link.
1655
	 * @param array   $args    An array of arguments overriding the defaults.
1656
	 * @param object  $comment The object of the comment being replied.
1657
	 * @param WP_Post $post    The WP_Post object.
1658
	 */
1659
	return apply_filters( 'comment_reply_link', $args['before'] . $link . $args['after'], $args, $comment, $post );
1660
}
1661
1662
/**
1663
 * Displays the HTML content for reply to comment link.
1664
 *
1665
 * @since 2.7.0
1666
 *
1667
 * @see get_comment_reply_link()
1668
 *
1669
 * @param array       $args    Optional. Override default options.
1670
 * @param int         $comment Comment being replied to. Default current comment.
1671
 * @param int|WP_Post $post    Post ID or WP_Post object the comment is going to be displayed on.
1672
 *                             Default current post.
1673
 * @return mixed Link to show comment form, if successful. False, if comments are closed.
1674
 */
1675
function comment_reply_link($args = array(), $comment = null, $post = null) {
1676
	echo get_comment_reply_link($args, $comment, $post);
1677
}
1678
1679
/**
1680
 * Retrieve HTML content for reply to post link.
1681
 *
1682
 * @since 2.7.0
1683
 *
1684
 * @param array $args {
1685
 *     Optional. Override default arguments.
1686
 *
1687
 *     @type string $add_below  The first part of the selector used to identify the comment to respond below.
1688
 *                              The resulting value is passed as the first parameter to addComment.moveForm(),
1689
 *                              concatenated as $add_below-$comment->comment_ID. Default is 'post'.
1690
 *     @type string $respond_id The selector identifying the responding comment. Passed as the third parameter
1691
 *                              to addComment.moveForm(), and appended to the link URL as a hash value.
1692
 *                              Default 'respond'.
1693
 *     @type string $reply_text Text of the Reply link. Default is 'Leave a Comment'.
1694
 *     @type string $login_text Text of the link to reply if logged out. Default is 'Log in to leave a Comment'.
1695
 *     @type string $before     Text or HTML to add before the reply link. Default empty.
1696
 *     @type string $after      Text or HTML to add after the reply link. Default empty.
1697
 * }
1698
 * @param int|WP_Post $post    Optional. Post ID or WP_Post object the comment is going to be displayed on.
1699
 *                             Default current post.
1700
 * @return false|null|string Link to show comment form, if successful. False, if comments are closed.
1701
 */
1702
function get_post_reply_link($args = array(), $post = null) {
1703
	$defaults = array(
1704
		'add_below'  => 'post',
1705
		'respond_id' => 'respond',
1706
		'reply_text' => __('Leave a Comment'),
1707
		'login_text' => __('Log in to leave a Comment'),
1708
		'before'     => '',
1709
		'after'      => '',
1710
	);
1711
1712
	$args = wp_parse_args($args, $defaults);
1713
1714
	$post = get_post($post);
1715
1716
	if ( ! comments_open( $post->ID ) ) {
1717
		return false;
1718
	}
1719
1720
	if ( get_option('comment_registration') && ! is_user_logged_in() ) {
1721
		$link = sprintf( '<a rel="nofollow" class="comment-reply-login" href="%s">%s</a>',
1722
			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...
1723
			$args['login_text']
1724
		);
1725
	} else {
1726
		$onclick = sprintf( 'return addComment.moveForm( "%1$s-%2$s", "0", "%3$s", "%2$s" )',
1727
			$args['add_below'], $post->ID, $args['respond_id']
1728
		);
1729
1730
		$link = sprintf( "<a rel='nofollow' class='comment-reply-link' href='%s' onclick='%s'>%s</a>",
1731
			get_permalink( $post->ID ) . '#' . $args['respond_id'],
1732
			$onclick,
1733
			$args['reply_text']
1734
		);
1735
	}
1736
	$formatted_link = $args['before'] . $link . $args['after'];
1737
1738
	/**
1739
	 * Filters the formatted post comments link HTML.
1740
	 *
1741
	 * @since 2.7.0
1742
	 *
1743
	 * @param string      $formatted The HTML-formatted post comments link.
1744
	 * @param int|WP_Post $post      The post ID or WP_Post object.
1745
	 */
1746
	return apply_filters( 'post_comments_link', $formatted_link, $post );
1747
}
1748
1749
/**
1750
 * Displays the HTML content for reply to post link.
1751
 *
1752
 * @since 2.7.0
1753
 *
1754
 * @see get_post_reply_link()
1755
 *
1756
 * @param array       $args Optional. Override default options,
1757
 * @param int|WP_Post $post Post ID or WP_Post object the comment is going to be displayed on.
1758
 *                          Default current post.
1759
 * @return string|bool|null Link to show comment form, if successful. False, if comments are closed.
1760
 */
1761
function post_reply_link($args = array(), $post = null) {
1762
	echo get_post_reply_link($args, $post);
1763
}
1764
1765
/**
1766
 * Retrieve HTML content for cancel comment reply link.
1767
 *
1768
 * @since 2.7.0
1769
 *
1770
 * @param string $text Optional. Text to display for cancel reply link. Default empty.
1771
 * @return string
1772
 */
1773
function get_cancel_comment_reply_link( $text = '' ) {
1774
	if ( empty($text) )
1775
		$text = __('Click here to cancel reply.');
1776
1777
	$style = isset($_GET['replytocom']) ? '' : ' style="display:none;"';
1778
	$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...
1779
1780
	$formatted_link = '<a rel="nofollow" id="cancel-comment-reply-link" href="' . $link . '"' . $style . '>' . $text . '</a>';
1781
1782
	/**
1783
	 * Filters the cancel comment reply link HTML.
1784
	 *
1785
	 * @since 2.7.0
1786
	 *
1787
	 * @param string $formatted_link The HTML-formatted cancel comment reply link.
1788
	 * @param string $link           Cancel comment reply link URL.
1789
	 * @param string $text           Cancel comment reply link text.
1790
	 */
1791
	return apply_filters( 'cancel_comment_reply_link', $formatted_link, $link, $text );
1792
}
1793
1794
/**
1795
 * Display HTML content for cancel comment reply link.
1796
 *
1797
 * @since 2.7.0
1798
 *
1799
 * @param string $text Optional. Text to display for cancel reply link. Default empty.
1800
 */
1801
function cancel_comment_reply_link( $text = '' ) {
1802
	echo get_cancel_comment_reply_link($text);
1803
}
1804
1805
/**
1806
 * Retrieve hidden input HTML for replying to comments.
1807
 *
1808
 * @since 3.0.0
1809
 *
1810
 * @param int $id Optional. Post ID. Default current post ID.
1811
 * @return string Hidden input HTML for replying to comments
1812
 */
1813
function get_comment_id_fields( $id = 0 ) {
1814
	if ( empty( $id ) )
1815
		$id = get_the_ID();
1816
1817
	$replytoid = isset($_GET['replytocom']) ? (int) $_GET['replytocom'] : 0;
1818
	$result  = "<input type='hidden' name='comment_post_ID' value='$id' id='comment_post_ID' />\n";
1819
	$result .= "<input type='hidden' name='comment_parent' id='comment_parent' value='$replytoid' />\n";
1820
1821
	/**
1822
	 * Filters the returned comment id fields.
1823
	 *
1824
	 * @since 3.0.0
1825
	 *
1826
	 * @param string $result    The HTML-formatted hidden id field comment elements.
1827
	 * @param int    $id        The post ID.
1828
	 * @param int    $replytoid The id of the comment being replied to.
1829
	 */
1830
	return apply_filters( 'comment_id_fields', $result, $id, $replytoid );
1831
}
1832
1833
/**
1834
 * Output hidden input HTML for replying to comments.
1835
 *
1836
 * @since 2.7.0
1837
 *
1838
 * @param int $id Optional. Post ID. Default current post ID.
1839
 */
1840
function comment_id_fields( $id = 0 ) {
1841
	echo get_comment_id_fields( $id );
1842
}
1843
1844
/**
1845
 * Display text based on comment reply status.
1846
 *
1847
 * Only affects users with JavaScript disabled.
1848
 *
1849
 * @internal The $comment global must be present to allow template tags access to the current
1850
 *           comment. See https://core.trac.wordpress.org/changeset/36512.
1851
 *
1852
 * @since 2.7.0
1853
 *
1854
 * @global WP_Comment $comment Current comment.
1855
 *
1856
 * @param string $noreplytext  Optional. Text to display when not replying to a comment.
1857
 *                             Default false.
1858
 * @param string $replytext    Optional. Text to display when replying to a comment.
1859
 *                             Default false. Accepts "%s" for the author of the comment
1860
 *                             being replied to.
1861
 * @param string $linktoparent Optional. Boolean to control making the author's name a link
1862
 *                             to their comment. Default true.
1863
 */
1864
function comment_form_title( $noreplytext = false, $replytext = false, $linktoparent = true ) {
1865
	global $comment;
1866
1867
	if ( false === $noreplytext ) $noreplytext = __( 'Leave a Reply' );
1868
	if ( false === $replytext ) $replytext = __( 'Leave a Reply to %s' );
1869
1870
	$replytoid = isset($_GET['replytocom']) ? (int) $_GET['replytocom'] : 0;
1871
1872
	if ( 0 == $replytoid )
1873
		echo $noreplytext;
1874
	else {
1875
		// Sets the global so that template tags can be used in the comment form.
1876
		$comment = get_comment($replytoid);
1877
		$author = ( $linktoparent ) ? '<a href="#comment-' . get_comment_ID() . '">' . get_comment_author( $comment ) . '</a>' : get_comment_author( $comment );
1878
		printf( $replytext, $author );
1879
	}
1880
}
1881
1882
/**
1883
 * List comments.
1884
 *
1885
 * Used in the comments.php template to list comments for a particular post.
1886
 *
1887
 * @since 2.7.0
1888
 *
1889
 * @see WP_Query->comments
1890
 *
1891
 * @global WP_Query $wp_query
1892
 * @global int      $comment_alt
1893
 * @global int      $comment_depth
1894
 * @global int      $comment_thread_alt
1895
 * @global bool     $overridden_cpage
1896
 * @global bool     $in_comment_loop
1897
 *
1898
 * @param string|array $args {
1899
 *     Optional. Formatting options.
1900
 *
1901
 *     @type object $walker            Instance of a Walker class to list comments. Default null.
1902
 *     @type int    $max_depth         The maximum comments depth. Default empty.
1903
 *     @type string $style             The style of list ordering. Default 'ul'. Accepts 'ul', 'ol'.
1904
 *     @type string $callback          Callback function to use. Default null.
1905
 *     @type string $end-callback      Callback function to use at the end. Default null.
1906
 *     @type string $type              Type of comments to list.
1907
 *                                     Default 'all'. Accepts 'all', 'comment', 'pingback', 'trackback', 'pings'.
1908
 *     @type int    $page              Page ID to list comments for. Default empty.
1909
 *     @type int    $per_page          Number of comments to list per page. Default empty.
1910
 *     @type int    $avatar_size       Height and width dimensions of the avatar size. Default 32.
1911
 *     @type string $reverse_top_level Ordering of the listed comments. Default null. Accepts 'desc', 'asc'.
1912
 *     @type bool   $reverse_children  Whether to reverse child comments in the list. Default null.
1913
 *     @type string $format            How to format the comments list.
1914
 *                                     Default 'html5' if the theme supports it. Accepts 'html5', 'xhtml'.
1915
 *     @type bool   $short_ping        Whether to output short pings. Default false.
1916
 *     @type bool   $echo              Whether to echo the output or return it. Default true.
1917
 * }
1918
 * @param array $comments Optional. Array of WP_Comment objects.
1919
 */
1920
function wp_list_comments( $args = array(), $comments = null ) {
1921
	global $wp_query, $comment_alt, $comment_depth, $comment_thread_alt, $overridden_cpage, $in_comment_loop;
1922
1923
	$in_comment_loop = true;
1924
1925
	$comment_alt = $comment_thread_alt = 0;
1926
	$comment_depth = 1;
1927
1928
	$defaults = array(
1929
		'walker'            => null,
1930
		'max_depth'         => '',
1931
		'style'             => 'ul',
1932
		'callback'          => null,
1933
		'end-callback'      => null,
1934
		'type'              => 'all',
1935
		'page'              => '',
1936
		'per_page'          => '',
1937
		'avatar_size'       => 32,
1938
		'reverse_top_level' => null,
1939
		'reverse_children'  => '',
1940
		'format'            => current_theme_supports( 'html5', 'comment-list' ) ? 'html5' : 'xhtml',
1941
		'short_ping'        => false,
1942
		'echo'              => true,
1943
	);
1944
1945
	$r = wp_parse_args( $args, $defaults );
1946
1947
	/**
1948
	 * Filters the arguments used in retrieving the comment list.
1949
	 *
1950
	 * @since 4.0.0
1951
	 *
1952
	 * @see wp_list_comments()
1953
	 *
1954
	 * @param array $r An array of arguments for displaying comments.
1955
	 */
1956
	$r = apply_filters( 'wp_list_comments_args', $r );
1957
1958
	// Figure out what comments we'll be looping through ($_comments)
1959
	if ( null !== $comments ) {
1960
		$comments = (array) $comments;
1961
		if ( empty($comments) )
1962
			return;
1963 View Code Duplication
		if ( 'all' != $r['type'] ) {
1964
			$comments_by_type = separate_comments($comments);
1965
			if ( empty($comments_by_type[$r['type']]) )
1966
				return;
1967
			$_comments = $comments_by_type[$r['type']];
1968
		} else {
1969
			$_comments = $comments;
1970
		}
1971
	} else {
1972
		/*
1973
		 * If 'page' or 'per_page' has been passed, and does not match what's in $wp_query,
1974
		 * perform a separate comment query and allow Walker_Comment to paginate.
1975
		 */
1976
		if ( $r['page'] || $r['per_page'] ) {
1977
			$current_cpage = get_query_var( 'cpage' );
1978
			if ( ! $current_cpage ) {
1979
				$current_cpage = 'newest' === get_option( 'default_comments_page' ) ? 1 : $wp_query->max_num_comment_pages;
1980
			}
1981
1982
			$current_per_page = get_query_var( 'comments_per_page' );
1983
			if ( $r['page'] != $current_cpage || $r['per_page'] != $current_per_page ) {
1984
				$comment_args = array(
1985
					'post_id' => get_the_ID(),
1986
					'orderby' => 'comment_date_gmt',
1987
					'order' => 'ASC',
1988
					'status' => 'approve',
1989
				);
1990
1991
				if ( is_user_logged_in() ) {
1992
					$comment_args['include_unapproved'] = get_current_user_id();
1993
				} else {
1994
					$commenter = wp_get_current_commenter();
1995
					if ( $commenter['comment_author_email'] ) {
1996
						$comment_args['include_unapproved'] = $commenter['comment_author_email'];
1997
					}
1998
				}
1999
2000
				$comments = get_comments( $comment_args );
2001
2002 View Code Duplication
				if ( 'all' != $r['type'] ) {
2003
					$comments_by_type = separate_comments( $comments );
0 ignored issues
show
It seems like $comments defined by get_comments($comment_args) on line 2000 can also be of type integer; however, separate_comments() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

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