Skip to main content

Including form values in an email

An article from ComputerMinds - Building with Drupal in the UK since 2005
26th Jun 2018

James Williams

Senior Developer
Hey, you seem to look at this article a lot! Why not Bookmark this article so you can find it easily in the future?

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!

Hi, thanks for reading

ComputerMinds are the UK’s Drupal specialists with offices in Bristol and Coventry. We offer a range of Drupal services including Consultancy, Development, Training and Support. Whatever your Drupal problem, we can help.