Override the Drupal Contact Form

Last week a client of ours at CHROMATIC requested an addition to the default contact form that ships with Drupal. Essentially, they just wanted to add a required “Phone Number” text field to the form. Additionally, they wanted this value to be sent along with the email that the contact module sends. One solution would have been to ditch the contact.module and just whip up a new page using the WebForm module. The other solution is to override both the form/email using the following hooks respectively in our own module:

I’ve written a similar post regarding overriding drupal forms, including element-specific validation on our company blog previously, which this tutorial will borrow from heavily – but this particular problem involves one more step: Overriding the email created by contact.module.

First, we need to override the contact form:

<?php
function yourModuleName_form_alter(&$form, $form_state, $form_id) {
  switch(
$form_id) {
      case
'contact_mail_page': // the value we stole from the rendered form
       
$form['phone'] = array(
             
'#type' => 'textfield',
             
'#title' => t('Phone Number'),
             
'#size' => 60,
             
'#maxlength' => 128,
             
'#required' => <span class="caps">TRUE</span>,
             
'#element_validate' => array('form_overrides_phone_validate'),
            );
            
      break;
  }
}

?>

Basically, here we tell Drupal that any time a form with the ID of ‘contact_mail_page’ is rendered, add a new “phone” field. We set it to be required and provide our own element-specific validation to ensure proper validation. You only need this if the element is required. Here is the code for the validation function:

<?php
function yourModuleName_phone_validate($element, &$form_state) {
  if(empty(
$element['#value'])) {
   
form_error($element, t('Please provide a phone number.'));
  }
}
?>

Element-specific validations can be a great way to extend existing fields too, not just new ones. There are tons of possible applications, but I’ll write about that some other time.

Ok, so now that we’ve got Drupal to add the field as well as validate it, we need to add that value to the email that contact.module sends. This process is very similar to overriding forms within Drupal. We use hook_mail_alter() and switch on the “Message ID” instead of the “Form ID”.

  • Note: * You can use *hook_form_alter and hook_form_alter more than one form or email. Just provide additional cases in your switch statement.

When modules use drupal_mail() for building and sending email messages, they must provide an ID to uniquely identify that message – in the same way that each form should have a unique ID. This is the key for tapping in and overriding the message. Here’s how you do it:

<?php
function form_overrides_mail_alter(&$message) {
  switch(
$message['id']) {
    case
'contact_page_mail':
     
$phone = $message['params']['phone'];
     
$name = $message['params']['name'];
      if (!empty(
$phone)){
             
$message['body'][2] = $message['body'][1];
             
$message['body'][1] = 'Phone number of '.$name.': '.$phone;
      }
    break;
  }
}
?>

The key here again is the $message[‘id’], which is constructed using the following format:

  • moduleName_messageKey

Once you’ve tapped in, you are free to provide any customizations that you’d like – pretty awesome stuff! The coolest part is you can basically do this with any email drupal sends, core or otherwise.

Source code included below. Happy Drupaling.

AttachmentSize
form_overrides.zip2.04 KB

Comments

Guest's picture
Thanks for the great info, however I’ve been searching hours for a complete tutorial on how to modify the Contact form… You have touch on the most obvious issues, but… 1. How do you then re-order the fields in the Contact form? Say I want the Phone to go after the subject? Using “Weight on -1 brings it to the top. Using weight of 1 puts it at the bottom. 2. How do you get ALL the fields to be included in the email sent to the site owner? 3. How do you remove other fields…say I don’t want the Category select box on my contact form. Any incite? If so, you will have the most complete how-to in modifying the Contact form. Thanks.
Markosaurus's picture
I’m trying to reorder the fields as well. I thought a manual re-rder based on weight (set manually for each) should work, but it doesn’t. I also tried setting them from an array, and that doesn’t work either. Hmmm, neither of these work; $form[‘name’] = array( ‘#weight’ => ‘1’); $form[‘mail’] = array( ‘#weight’ => ‘2’); $form[‘subject’] = array( ‘#weight’ => ‘3’); $form[‘phone’] = array( ‘#weight’ => ‘4’); $form[‘cid’] = array( ‘#weight’ => ‘5’); $form[‘message’] = array( ‘#weight’ => ‘6’); $form[‘submit’] = array( ‘#weight’ => ‘7’); $order = array(‘name’,‘mail’, ‘subject’, ‘phone’, ‘cid’,‘message’,‘submit’); foreach($order as $key => $field) { $form[$field][’#weight’] = $key; } I don’t know how drupal handles weights in this case…anyone know?
xar's picture
good work. Exactly what i was looking for. Saved me creating form using webform module.
Yeti's picture

Nice post! And I love the new blog!

chris's picture

thanks dave – glad someone commented. Now I have a reason to style them up…