2

Should the comment_content in this example contain HTML? Or should it contain plain text?

$comment_id = wp_new_comment([
    'comment_post_ID' => 1,
    'comment_content' => 'Tom & Jerry', // or should this be 'Tom & Jerry'?
    'comment_type' => '',
    'user_id' => 1,
    // etc
]);

For completeness, does the same apply to wp_insert_comment too?

2
  • Can't you simply try this out? Should or should not probably depends on what exactly it is you want to achieve - which we don't know as it stands
    – kero
    Aug 29, 2018 at 11:09
  • 1
    Based on my reading of the source code, it just inserts the content as is into the database, and now I need to check to see if the database expects HTML, it's not obvious. I was hoping to simply find the answer in the documentation or in Google. I want to get it right to prevent improper escaping.
    – Flimm
    Aug 29, 2018 at 11:11

1 Answer 1

1

or should this be 'Tom & Jerry'?

It doesn't really matter. It's more important to consider if you don't know where the comment content is coming from. If you're inserting user input as the comment content then this should be escaped.

wp_new_comment() escapes and sanititizes the comment for you. It's designed to take the user input from the comment form directly and sanitise it before passing it to wp_insert_comment().

So this includes encoding HTML entitites (converting & to &) and filtering out disallowed HTML. It also does things like add the commenter's IP address to the comment.

So when using wp_new_comment() you shouldn't need to do any escaping and should enter the comment the same way the user would, with one important exception.

Both wp_new_comment() and wp_insert_comment() expect data to be slashed. WordPress automatically runs addslashes() on everything in $_POST, $_GET and $_REQUEST and these functions are expecting the data to be slashed because they are made to use data from those variables.

So if any of the data for the comment you're inserting includes quotes or slashes then you need to slash it with wp_slash() before inserting:

$args = [
    'comment_post_ID' => 1,
    'comment_content' => 'Tom\'s a cat',
    'comment_type' => '',
    'user_id' => 1,
];

$comment_id = wp_new_comment( wp_slash( $args ) );

Note that the slash I already added, Tom\'s was escaping it for PHP purposes, and still needs to be slashed.

The silly thing is that the first thing that happens in wp_insert_comment() is that it runs wp_unslash(). So we're adding slashes just for them to be removed immediately. But it needs to be done for consistency with the $_POST variable and so that slashes that might be part of the content aren't incorrectly removed.

3
  • I don't think wp_new_comment escapes the input, Tom & Jerry gets turned into Tom & Jerry, but Tom & Jerry remains as Tom & Jerry instead of Tom & Jerry.
    – Flimm
    Aug 30, 2018 at 6:04
  • I think knowing the rules of when to escape and when not to escape is important. As if to prove this point, the first paragraph in your answer I think was interpreted as HTML when you did not expect it to.
    – Flimm
    Aug 30, 2018 at 6:05
  • It does escape the input. wp_new_comment() calls wp_filter_comment() on all the data. This applies the pre_comment_content filters to the comment content. By default wp_filter_kses or wp_filter_post_kses (depending on the user role) is applied to pre_comment_content. One of the things wp_kses does is run wp_kses_normalize_entities(), which runs functions like wp_kses_named_entities(), wp_kses_normalize_entities2() and wp_kses_normalize_entities3(). This whole process ensures entities are not double-escaped. Aug 30, 2018 at 6:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.