Skip to main content

Including form values in an email

26th Jun 2018

James Williams

Senior Developer

Let's say you've built a custom form for your Drupal 8 site. It contains various elements for input (name, email address, a message, that kind of thing), and you want to send the submitted values in an email to someone (perhaps a site admin). That's a pretty common thing to need to do.

This could be done with Drupal's core contact forms, webforms, or similar -- but there are cases when a bespoke form is needed, for example, to allow some special business logic to be applied to its input or the form presentation. The drawback of a custom form is that you won't get nice submission emails for free, but they can be done quite easily, with the token module (you'll need that installed).

In your form's submission handler, send an email using the mail manager service (I'll assume you can already inject that into your form, read the documentation if you need help with that):

<?php

  $params = [
    'values' => $form_state->getValues(),
  ];
  // The 'plugin.manager.mail' service is the one to use for $mailManager.
  $mailManager->mail('mymodule', 'myform_submit', 'admin@example.com, 'en', $params);

Then create a hook_mail() in your .module file, with a matching key ('myform_submit' in my example):

<?php

/**
 * Implements hook_mail().
 */
function mymodule_mail($key, &$message, $params) {
  switch ($key) {
    case 'myform_submit':
      $token_service = \Drupal::token();
      $token_data = [
        'array' => $params['values'],
      ];

      // In this example, put the submitted value from a 'first_name' element 
      // into the subject.
      $subject = 'Submission from [array:value:first_name]';
      $message['subject'] = $token_service->replace($subject, $token_data, ['clear' => TRUE]);

      // Each submitted value can be included in the email body as a token. My
      // form had 'first_name', 'last_name', 'color' and 'birthdate' elements.
      $body = <<<EOT
The mymodule form was submitted by [array:value:first_name] [array:value:last_name].
They like the colour [array:value:color], and their birthday is [array:value:birthdate].
>>>;
      $message['body'] = [
        $token_service->replace($body, $token_data, ['clear' => TRUE]),
      ];
      break;
  }
}

Spot the [array:value:thing] tokens! Using these 'array' tokens makes it really easy to include the whatever input gets submitted by visitors to this custom form on your Drupal site. This is most useful when the email body is configurable, so editors can move the tokens around as placeholders within the content, and regardless of the form's structure. By the way, the submitted values do not get sanitized - although if your email is just plain text, that's probably not a problem.

There are more array tokens you can use too, such as ones to return a comma-separated list of all items in an array, a count of items, or just the first/last item. See the original issue for examples. These tokens are available in Token's Drupal 7 version too!