Create Comments in Drupal 8 Programmatically

Gabe Sullice

Creating comments programmatically in Drupal 8 is incredibly easy once you know just which fields are required and why. In Drupal 8, comments are now full-featured, fieldable entities — just like nodes or taxonomy terms. In addition to unifying the way we create content, comments, and other entities, this has made Drupal’s commenting system much more robust and flexible.

Recently, we needed to allow certain users to leave short notes about a node (almost like revision notes without the revisions). Only certain users would be able to leave these notes and the notes are added as part of a custom form. This meant that we needed to handle comment creation ourselves. After much googling, we finally figured out just how to create comments manually.

To create a new comment, you need to create a comment entity in code and then save it. There are a lot of required fields and we'll go over each one below. But first, here’s the code:

// To create a new comment entity, we'll need `use` (import) the Comment class.
use Drupal\comment\Entity\Comment;
// The function name doesn't matter. Just put the the function body where you need it.
function my_modules_function_or_method() {
  // First, we need to create an array of field values for the comment.
  $values = [
    // These values are for the entity that you're creating the comment for, not the comment itself.
    'entity_type' => 'node',            // required.
    'entity_id'   => 42,                // required.
    'field_name'  => 'comment',         // required.
    // The user id of the comment's 'author'. Use 0 for the anonymous user.
    'uid' => 0,                         // required.
    // These values are for the comment itself.
    'comment_type' => 'comment',        // required.
    'subject' => 'My Awesome Comment',  // required.
    'comment_body' => $body,            // optional.
    // Whether the comment is 'approved' or not.
    'status' => 1,                      // optional. Defaults to 0.
  // This will create an actual comment entity out of our field values.
  $comment = Comment::create($values);
  // Last, we actually need to save the comment to the database.

The first three required fields are telling Drupal what entity the comment should be attached to.

  • entity_type: This is the entity to which you want to attach the comment. If you're creating a comment on an article or basic page, for example, this would be node.
  • entity_id: The id of the entity to which you want to attach the comment. If you're attaching to a node, this would be its nid.
  • field_name: The field on the entity to which this comment should be attached. Note: This is something new in Drupal 8. In D8, you can have multiple comment fields on an entity and those comments' fields can use different comment types. The default article content type is the only content type that comes with a comment field. If you want to enable comments on your own content type, you have to add your own comment field which receives a unique machine name. That machine name is the value you would put here.

The uid field tells Drupal which user authored the comment.

The remaining values are all specific to the comment itself.

  • comment_type: The type of comment to create. Note: This is new in Drupal 8 too. You can have different types of comments with completely different fields, just like nodes or taxonomy terms. Think of this as the comment "bundle" if you're familiar with that term. The default comment type is just comment.
  • subject: Every comment has a subject field, just like the title field on a node.
  • comment_body: This field is provided by default just like the body field on nodes. However, it can be removed like any other field.
  • status: Set this to 1 if you would like the comment to be automatically approved. Otherwise, an administrator will need to approve it.
  • field_foobar: This isn't in the example, but comment types can have custom fields just like any other content entity. If you have custom fields on your comment type, you can just use the field’s machine name and provide a default value here.