When using theme_webform_mail_headers to alter "Subject" or "To", the hook is applied each time a component that is a conditional e-mail recipient is present. But somehow, the headers seems to be merged twice or something, so "Subject" or "To" is present twice in the mail header, for example.

I checked to see if the hook was called twice with the watchdog, but it does not.

function mytheme_webform_mail_headers($form_values, $node, $sid, $cid) {
 if ($node->nid == XXX && $cid == X) {
  $headers = array(
    'X-Mailer' => 'Drupal Webform (PHP/'. phpversion() .')',
    'Subject' => 'Test Subject', // appears twice in the mail
    'To' => 'test@test.com', // appears twice in the mail
  );
  watchdog('Webform', 'theme_webform_mail_headers has been called');
 }
 return $headers;
}
CommentFileSizeAuthor
#5 webform_double.patch1.08 KBjide

Comments

jide’s picture

I have made a typo above, the function should render an array otherwise.
Anyway, in the Webform Debugger everything seems correct :

E-mail Headers:
Array
(
    [X-Mailer] => Drupal Webform (PHP/5.2.0-8+etch13)
    [Subject] => Test Subject
    [To] => test@test.com
)

But, in the effective mail header, Subject and To appear twice, while it seems that X-Mailer appears only once.
I made several tests, and i can tell this is not related to multiple email components fields, and to multiple mail adresses neither.

quicksketch’s picture

The Webform subject and "to" fields are determined by the configuration entered when editing the Webform node. It's intentional the these options override those set in the theme function, since the theme function doesn't know which address it's sending to. Could you describe the scenario in which you'd want to hard-code values in the theme function, rather than using the node configuration to set those headers?

jide’s picture

Status: Needs review » Postponed (maintainer needs more info)

Sorry if my example was a little generic, but i do not want to hardcode these, but rather override them.
In the theme function description, there is :

/*
 * @return
 *   An array of headers to be used when sending a webform email. If headers
 *   for "From", "To", or "Subject" are set, they will take precendence over
 *   the values set in the webform configuration.
*/

The scenarios where i would want to override these values is for example if i would like to alter the subject of the mail message, using a combination of custom string like '[My Site] ' for example, and the subject from a field in the form. Using the UI, i can only choose the field value.

The other scenario is more complex : I have two selects.
The first one has 2 values, one with an email adress. Email is sent to this field.
The second one has many locations with many email adresses. Email is sent to this field too.
In this case, when a user chooses the email value in the first select, the email should be sent to this email, but not to the location field's email, nevertheless the user should be able to choose a location.

I found another way for my own case, using form_alter and a submit function, but i was curious, and thought that may be a bug ? These values should not apeear twice in the email header anyway ?

Thanks for answering and for your great work.

quicksketch’s picture

Oh hmm. Looks like I should follow my own help text then. :P

I looked at the code here, and it looks like it *should* be doing what is described.

      $headers[$cid] = theme(array('webform_mail_headers_'. $node->nid, 'webform_mail_headers'), $form_state['values'], $node, $sid, $cid);

      // Assemble the FROM string.
      if (isset($headers[$cid]['From'])) {
        $froms[$cid] = $headers[$cid]['From'];
      }
      elseif (strlen($email_from_name) > 0) {
        $froms[$cid] = '"'. mime_header_encode($email_from_name) .'" <'. $email_from_address .'>';
      }
      else {
        $froms[$cid] = $email_from_address;
      }

      // Update the subject if set in the themed headers.
      if (isset($headers[$cid]['Subject'])) {
        $subjects[$cid] = $headers[$cid]['Subject'];
      }
      else {
        $subjects[$cid] = $email_subject;
      }

      // Update the to e-mail if set in the themed headers.
      if (isset($headers[$cid]['To'])) {
        $emails[$cid] = $headers[$cid]['To'];
      }

So I'm not quite sure why the themed version isn't taking precedence.

jide’s picture

StatusFileSize
new1.08 KB

Definitely, you should, the developer of this module knows what he's saying ;)

After a lot of testing/debuging i finally got it !

The drupal_mail function is given $subjects[$cid] as the subject argument and $headers[$cid] as the header argument. So if we set $headers['Subject'], it will be set twice : once in the subject, once in the header. The same stands for the $headers['To'] and $headers['From'] :

      $headers[$cid] = theme(array('webform_mail_headers_'. $node->nid, 'webform_mail_headers'), $form_state['values'], $node, $sid, $cid);

      // Assemble the FROM string.
      if (isset($headers[$cid]['From'])) {
        $froms[$cid] = $headers[$cid]['From'];
        unset($headers[$cid]['From']); // Unset the header item
      }
      elseif (strlen($email_from_name) > 0) {
        $froms[$cid] = '"'. mime_header_encode($email_from_name) .'" <'. $email_from_address .'>';
      }
      else {
        $froms[$cid] = $email_from_address;
      }

      // Update the subject if set in the themed headers.
      if (isset($headers[$cid]['Subject'])) {
        $subjects[$cid] = $headers[$cid]['Subject'];
        unset($headers[$cid]['Subject']); // Unset the header item
      }
      else {
        $subjects[$cid] = $email_subject;
      }

      // Update the to e-mail if set in the themed headers.
      if (isset($headers[$cid]['To'])) {
        $emails[$cid] = $headers[$cid]['To'];
        unset($headers[$cid]['To']); // Unset the header item
      }

      // ...
      
      drupal_mail('webform', 'submission', $single_address, user_preferred_language($user), array('message' => $messages[$cid], 'subject' => $subjects[$cid], 'headers' => $headers[$cid]), $froms[$cid]);

Here is an attached patch.

quicksketch’s picture

Status: Postponed (maintainer needs more info) » Needs review

Awesome! I'll put this in when I get a minute to review.

quicksketch’s picture

Status: Postponed (maintainer needs more info) » Fixed

Committed to Drupal 5 and 6, thanks for the sleuthing!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.