TrevorTwining.com

Trevor Twining
phone: 905-228-9990 cel: 289-407-3957
email trevortwining _AT_ gmail.com

Overriding contact.module, no core hacking required!

Wow, this was a really tough one. I learned how to totally redesign the Drupal contact form without hacking a single line of core.

Here's what we needed.

First, it will help to tell you that I put this code in a custom client-specific module. I use this approach when developing client sites. I create a module with the client name and then put any customizations that are needed to forms, theme functions, etc. inside of it. It helps keep things better maintaned. If enough customizations are needed, I suppose I would then put each grouping into its own module, and keep them within the same module category.

The project I was working on required a contact form that contained the following things that are not provided by the core contact.module or any related contrib modules.

  • a daytime contact number
  • an evening contact number

Also, I had to remove the message body and subject that would normally appear.

Now, I had enough experience with hook_form_alter that I could modify the form to my heart's desire. The code for that is below:

<?php
function contactoverride_form_alter($form_id, &$form){
  if(
$form_id == 'contact_mail_page'){
   
//this is the name of the form from contact.module
    //add new fields/values
   
$form['day_phone'] = array(
   
'#type' => 'textfield',
   
'#title' => 'Daytime phone',
   
'#required' => TRUE,
   
'#weight' => 1,
    );
   
$form['evening_phone'] = array(
   
'#type' => 'textfield',
   
'#title' => 'Evening phone',
   
'#required' => TRUE,
   
'#weight' => 2,
    );
   
$form['agreement'] = array(
   
'#type' => 'checkbox',
   
'#title' => 'Yes, I would like to learn more.',
   
'#weight' => -29,
   
'#attributes' => array('class' => 'agreement'),
   
'#prefix' => '<div class="wideme">',
   
'#suffix' => '</div>',
    );
  
//this element is added to help theme the form. completely optional.
   
$form['opening'] = array(
               
'#value' => '<div id="formopening">',
               
'#weight' => -30,
                );
   
$form['closing'] = array(
               
'#value' => '</div>',
               
'#weight' => 40,
                ); 
  }
}
?>

However, I had never overwritten the submit and validate functions for a *core* form before. I was worried that I might have to resort to hacking core.

Hacking core? NEVER!

Googling the problem and searching on drupal.org didn't provide much help.

A great resource was Pro Drupal Development by Matt Westgate and John VanDyk. It helped provide the insight into the fundamentals that I was missing. From that I figured what I needed to do to overwrite the forms.

The first step is to redirect the function that handles the validate and submit events. To do that, I needed a specific value to be set in my form array for each task. I accomplished this in my hook_form_alter() function. Note that this is clearer when shown in context with the full code sample below.

<?php
$form
['#submit'] = array('contactoverride_form_submit' => array($extra_info));
?>

Next, I needed to write the functions that did the validation and submission. In order to make them work *mostly* the same as how they do in contact.module, I copied and pasted their respective functions into mine. and then made the modifications I needed. You can see the completed functions below.

The submission function basically works the same as the core contact.module, but it modifies the message. My first instinct was to try and use hook_mail_alter() to accomplish this, but I quickly realized that I wouldn't have been able to work with anything inside the form submit if I took this approach.

After a bit of testing, I nailed down the bugs (most of them were related to the name of the submit function within the altered form) and got it finished.

Hope this helps anyone in the same situation.


full code sample

<?php
function contactoverride_form_alter($form_id, &$form){

  if(
$form_id == 'contact_mail_page'){
   
//this is the name of the form from contact.module
    //modify existing fields/values
   
$form['#submit'] = array('contactoverride_form_submit' => array($extra_info));//modifying the submit function
   
$form['name']['#weight'] = -1;
   
$form['mail']['#weight'] = -1;
   
   
$form['cid']['#weight'] = 2;
   
$form['cid']['#prefix'] = '<div class="hideme">'; // need to keep the category id field, but have it hidden.
   
$form['cid']['#suffix'] = '</div>';
   
$form['submit']['#weight'] = 32;
   
    unset(
$form['subject']); //unsetting these values because they're not needed on the form.
   
unset($form['message']);
    unset(
$form['copy']);
   
 
//add new fields/values
   
$form['day_phone'] = array(
   
'#type' => 'textfield',
   
'#title' => 'Daytime phone',
   
'#required' => TRUE,
   
'#weight' => 1,
    );

       
$form['evening_phone'] = array(
   
'#type' => 'textfield',
   
'#title' => 'Evening phone',
   
'#required' => TRUE,
   
'#weight' => 2,
    );
   
   
$form['agreement'] = array(
   
'#type' => 'checkbox',
   
'#title' => 'Yes, I would like to learn more.',
   
'#weight' => -29,
   
'#attributes' => array('class' => 'agreement'),
   
'#prefix' => '<div class="wideme">',
   
'#suffix' => '</div>',
    );
  
//this element is added to help theme the form. completely optional.
   
$form['opening'] = array(
               
'#value' => '<div id="formopening">',
               
'#weight' => -30,
                );
   
   
$form['closing'] = array(
               
'#value' => '</div>',
               
'#weight' => 40,
                );  
  }
     
}

function
contactoverride_form_submit($form_id,$form_values){

 
// E-mail address of the sender: as the form field is a text field,
  // all instances of \r and \n have been automatically stripped from it.
 
$from = $form_values['mail'];

 
// Compose the body:
  /*this is where I modified the message body.
  Notice that the message is first constructed
  as an array, and then assembled using implode() */
 
$message[] = t("!name sent a message using the contact form at !form.", array('!name' => $form_values['name'], '!form' => url($_GET['q'], NULL, NULL, TRUE)));
 
$message[] = $form_values['message'];
 
$message[] = '------------||| I N F O |||----------';
 
$message[] = 'Name: ' . $form_values['name'];
 
$message[] = 'Mail: ' . $form_values['mail'];
 
$message[] = 'Daytime Phone: ' . $form_values['day_phone'];
 
$message[] = 'Evening Phone: ' . $form_values['evening_phone'];

 
 
 
// Load the category information:
 
$contact = db_fetch_object(db_query("SELECT * FROM {contact} WHERE cid = %d", $form_values['cid']));
 
   
$message[] = 'Type of enquiry: ' . $contact->category;
 
 
// Tidy up the body:
 
foreach ($message as $key => $value) {
   
$message[$key] = wordwrap($value);
  }
 
 
// Format the category:
 
$subject = t('Choices:[!category] !subject', array('!category' => $contact->category, '!subject' => $form_values['subject']));

 
// Prepare the body:
 
$body = implode("\n\n", $message);

 
// Send the e-mail to the recipients:
 
drupal_mail('contact-page-mail', $contact->recipients, $subject, $body, $from);

 
// If the user requests it, send a copy.
 
if ($form_values['copy']) {
   
drupal_mail('contact-page-copy', $from, $subject, $body, $from);
  }

 
// Send an auto-reply if necessary:
 
if ($contact->reply) {
   
drupal_mail('contact-page-autoreply', $from, $subject, wordwrap($contact->reply), $contact->recipients);
  }

 
// Log the operation:
 
flood_register_event('contact');
 
watchdog('mail', t('%name-from sent an e-mail regarding %category.', array('%name-from' => $form_values['name'] ." <$from>", '%category' => $contact->category)));

 
// Update user:
 
drupal_set_message(t('Your message has been sent.'));

 
// Jump to home page rather than back to contact page to avoid contradictory messages if flood control has been activated.
 
return('');
}
?>

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.

Powered by Drupal