background image
HomeRecent PostsDrupalSearchTagsRSSContactAboutAccount
Eric.London's picture

A recent task that came my way way to create the functionality to capture email addresses using a simple subscription form. Since email is not a reliable means of capturing data, I used CCK to create nodes to capture the data and a view to show the results. First, I create a CCK node type called "email_subscription" which did not have a body or any custom fields, just the title for email address. I then created a view that shows the nodes in a table. Here's the module I created that generates a block module that contains the CCK node form. The block uses the CCK node form to capture the data. When the node is created, it uses the nodeapi hook to send a conformation email. There is also a function to validate the user's email address.

<?php
function MYMODULE_subscribe_block($op='list', $delta=0) {
 
// listing of blocks, such as on the admin/block page
 
if ($op == "list") {
   
$block[0]["info"] = t('Subscribe Block');
    return
$block;
  } else if (
$op == 'view') {
   
$block['subject'] = 'Subscribe';
   
$block['content'] = _MYMODULE_subscribe_block_main();
    return
$block;
  }
}

function
_MYMODULE_subscribe_block_main() {
 
// show the cck node form
 
return drupal_get_form('email_subscription_node_form',
    array(
     
'type' => 'email_subscription',
     
'uid' => $GLOBALS['user']->uid,
     
'name' => $GLOBALS['user']->name,
    )
  );
}

function
MYMODULE_subscribe_form_alter($form_id, &$form) {
  if (
$form_id == 'email_subscription_node_form') {
   
// remove preview button
   
unset($form['preview']);

   
// add custom validation
   
$form['#validate'] = array_merge(array('_MYMODULE_subscribe_node_form_validate' => array()), $form['#validate']);
  }
}

function
_MYMODULE_subscribe_node_form_validate($form_id, $form_values, $form) {
 
// validate title as email address
 
if (!valid_email_address($form_values['title'])) form_set_error('title', 'Email is not valid.');

 
// get list of already submitted emails
 
$sql = "select title from {node} where type = 'email_subscription'";

 
// if editing an existing node:
 
if ($form_values['nid']) $sql .= " and title!='" . db_escape_string($form_values['title']) . "'";

 
$resource = db_query($sql);
 
$results = array();
  while (
$row = db_fetch_array($resource)) $results[] = $row['title'];

 
// ensure email address has not already been subscribed
 
if (in_array($form_values['title'],$results)) form_set_error('title', 'Email has already been subscribed.');

}

function
MYMODULE_subscribe_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  if (
$node->type == 'email_subscription' && $op=='insert') {
   
// send email to user
   
mail($node->title, variable_get('site_name') . ' Subscription', 'Thank you for subscribing!', "From: " . variable_get('site_mail'));
  }
}
?>

Eric.London's picture

Although I am a big fan of the Drupal Forms API, sometimes I'll use CCK node forms as a quick and flexible alternative. This allows you to store the user submitted data as well as process the form. Here is a code snippet you can add to send the html generated from the node in an HTML email...

<?php
function MYMODULE_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  if (
$node->type == 'MYNODETYPE' && $op=='insert') {
   
$emailTo = variable_get('site_mail', 'MYEMAILADDRESS');
   
$emailFrom = 'info@' . $_SERVER['HTTP_HOST'];
       
   
// send email
   
_MYMODULE_send_node_email($node, $emailTo, $emailFrom);
       
  }
   
}

function
_MYMODULE_send_node_email(&$node, $emailTo, $emailFrom) {

  require_once(
'Mail.php');
  require_once(
'Mail/mime.php');

 
// create node html
 
$html = node_view($node, TRUE, FALSE, FALSE);
   
 
// get a list of node types
 
$nodeTypes = node_get_types();
   
 
$crlf = "\n";
 
$hdrs = array(
   
'From'    => $emailFrom,
   
'Subject' => $nodeTypes[$node->type]->name . ' Submitted',
  );
   
 
$mime = new Mail_mime($crlf);
 
//$mime->setTXTBody($text);  //TODO: you should also include a text version of your email
 
$mime->setHTMLBody($html);
 
$body = $mime->get();
 
$hdrs = $mime->headers($hdrs);
 
$mail =& Mail::factory('mail');
 
$mail->send($emailTo, $hdrs, $body);  

}
?>

Eric.London's picture

In certain situations, you might want to modify a node's form and functionality. In this example, I'll explain how to remove the title field from a node's form and add your own title later.

<?php
// using hook_form_alter to remove the node title input field...
function MYMODULE_form_alter($form_id, &$form) {
 
// ...code....
 
if ($form_id == 'MYNODETYPE_node_form' && arg(0)!='admin') {
    unset(
$form['title']);
  }
 
// ...code...
}

// using hook_nodeapi to add the title when the node form is submitted...
function MYMODULE_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
 
// ...code...
 
if ($node->type == 'MYNODETYPE' && $op == 'submit') {
   
// get a list of node types
   
$nodeTypes = node_get_types();
   
// set the node's title
   
$node->title = $nodeTypes[$node->type]->name;
  }
 
// ...code...
}
?>

Syndicate content