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.
| Attachment | Size |
|---|---|
| form_overrides.zip | 2.04 KB |

Comments
Nice post! And I love the new blog!
thanks dave – glad someone commented. Now I have a reason to style them up…