Pedro Posada | Alteration of the Simplenews module

Alteration of the Simplenews module

Posted on April 3, 2008 - 12:45pm
<< 44 of 50 >>

I was trying to build a custom user interface that would allow the user to create an e-mailer. I wanted to create a web-form with a number of options. The purpose of this was to make things as easy as possible to the user to add content and submit the e-mailer to the recipients.

I thought it would be a good idea to use the functionality already available in the Simplenews module. So I wrote a module that alters the Simplenews newsletter creation form and modifies the newsletter node as well. I wanted the user not to be able to modify the layout of the newsletter at all, just have him/her select a number of options and hit submit or preview.

I used the CCK module to create some forms and combine them with mine and then alter them using hook_form_alter. I also used Panels to show all the forms in the same page, but you can do this on a regular page as well.

This module is still in development, still needs a lot of work and rethinking.

I am posting the code just because there are a couple of things that are very useful in it and can help me and others in another projects.

Here is the code:

simplenews.info

; $Id.
name = Simplenews Alterate.
description = Alterate newsletters to create special layouts using CCK nodes.
version = "5.2"
package = Custom
dependencies = content simplenews
; recommended = panels formfilter imagecache

simple_news.install

<?php
// $Id: simplenews_alter.install,v 1 2008/01/18 10:40:00 pedrop Exp $

/**
* Implementation of hook_install().
*/
function simplenews_alter_install() {
 
db_query("UPDATE {system} SET weight = 10 WHERE name = 'simplenews_alter'");
 
drupal_set_message(t('Beginning installation of tables.'));
    switch (
$GLOBALS['db_type']){
        case
'mysql':
        case
'mysqli':
           
db_query("CREATE TABLE {simplenews_alter} (
                nid int NOT NULL default 0,
                header varchar(60) NULL default 0,
                main varchar(60) NULL default 0,
                valid_until varchar(30) NULL default 0,
                price varchar(30) NULL default 0,
                company_info varchar(60) NULL default 0,
                PRIMARY KEY (nid)
                ) /*!40100 DEFAULT CHARACTER SET utf8 */;"
           
);
           
$success = TRUE;
            break;
        default:
           
drupal_set_message(t('Unsupported database.'));
    }
    if(
$success){
       
drupal_set_message(t('The module installed tables successfully.'));
    }
    else {
       
drupal_set_message(t('The installation of module was unsuccessful.'), 'error');
    }
}

/**
* make sure hooks are invoked after cck main hooks
*/
function simplenews_alter_update_1() {
 
$ret = array();
 
$ret[] = update_sql("UPDATE {system} SET weight = 10 WHERE name = 'simplenews_alter'");
  return
$ret;
}
?>

simplenews_alter.module

<?php
/**
* @desc Implementation of hook_menu().
*/
function simplenews_alter_menu($may_cache){
   
    global
$user;
   
$items = array();
   
    if(
$may_cache){
       
$items[] = array('path' => 'emailer-creator/bouncer',
                       
'title' => t('Bouncer'),
                       
'callback' => 'simplenews_bouncer',
                       
'access' => user_access('access content'),
                       
'type' => MENU_CALLBACK
                       
);
    }
   
    return
$items;
}

/**
* @desc helper function to bounce back to the emailer page
*/
function simplenews_bouncer($nid = NULL){
    if(
is_numeric($nid)){
       
drupal_goto("node/".$nid."/edit");
    }else{
       
drupal_goto("emailer-creator");
    }
}

/**
* Implementation of hook_form_alter().
*/
function simplenews_alter_form_alter($form_id, &$form) {

    if (isset(
$form['#node_type']) && 'node_type_form' == $form_id) {
       
//this is a node settings form
   
}
    if (isset(
$form['#node']) && isset($form['#post']) && $form['#node']->type .'_node_form' == $form_id) {
       
//this is a node form
       
if($form['#node']->type == "simplenews"){
            
$simplenews_alter = simplenews_alter_form($form);
            
$form_values = array_merge($simplenews_alter, $form_values);

          
        }
       
        if(
$form['#node']->type == "header_image"){
           
$form['#redirect'] = "emailer-creator/bouncer"."/".arg(1);
            
//drupal_set_message("theme_simplenews_alter nid: <pre>". print_r($form, true) . "</pre>");
       
}
       
        if(
$form['#node']->type == "main_image"){
            
$form['#redirect'] = "emailer-creator/bouncer";
        }
    }
}

/**
* Implementation of hook_nodeapi().
*/
function simplenews_alter_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
    if(
$node->type == "simplenews"){
       
        if(
$op == 'validate'){
           
        }
       
        if(
$op == 'submit'){
          
           
//drupal_set_message("theme_simplenews_alter nid: <pre>". print_r($node, true) . "</pre>");
           
if($node->nid != ''){
               
simplenews_alter_form_submit($form, $node);
            }
           
        }
       
        if(
$op == 'insert'){
           
            
simplenews_alter_form_submit($form, $node);
            
        }
   
        if(
$op == 'view'){
           
           
$node->content['body']['#value'] = theme_simplenews_alter($form, $node);
           
//drupal_set_message("theme_simplenews_alter nid: <pre>". print_r($node, true) . "</pre>");
       
}
       
        if(
$op == 'edit'){
            
        }
       
        if(
$op == 'delete'){
            
            
db_query("DELETE FROM {simplenews_alter} WHERE nid = %d", $node->nid);
            
        }
    }
}

/**
* helper functions
*/

/**
* @desc settings for each newsletter
*/
function simplenews_alter_node_settings_form(&$form){
   
}

/**
* @desc fild that will be adedd to the newsletter issue form
*/
function simplenews_alter_form(&$form){
   
   
//$form = array();
   
   
$form['simplenews_alter'] = array(
       
'#type' => 'fieldset',
       
'#title' => t('Extra parameters.'),
       
'#weight' => -1,
       
'#collapsible' => TRUE,
       
'#collapsed' => TRUE
   
);
   
$form['simplenews_alter']['simplenews_alter_header'] = array(
         
'#type' => 'select',
         
'#title' => t('Select header image.'),
         
'#default_value' => db_result(db_query('SELECT header FROM {simplenews_alter} WHERE nid = %d',$form['#node']->nid)),
         
'#options' => _simplenews_alter_images_dropdown('header_image'),
         
'#description' => t('Image that will be shown in the header of the emailer.'),
         
'#theme' => 'simplenews_alter_select'
       
);
   
$form['simplenews_alter']['simplenews_alter_main'] = array(
         
'#type' => 'select',
         
'#title' => t('Select main image.'),
         
'#default_value' => db_result(db_query('SELECT main FROM {simplenews_alter} WHERE nid = %d',$form['#node']->nid)),
         
'#options' => _simplenews_alter_images_dropdown('main_image'),
         
'#description' => t('Image that will be shown in the side of the emailer.'),
         
'#theme' => 'simplenews_alter_select'
       
);
    
$form['simplenews_alter']['simplenews_alter_valid_until'] = array(
         
'#type' => 'textfield',
         
'#title' => t('Valid Until'),
         
'#default_value' => db_result(db_query('SELECT valid_until FROM {simplenews_alter} WHERE nid = %d',$form['#node']->nid)),
         
'#required' => TRUE
       
);
    
$form['simplenews_alter']['simplenews_alter_price'] = array(
         
'#type' => 'textfield',
         
'#title' => t('Price'),
         
'#default_value' => db_result(db_query('SELECT price FROM {simplenews_alter} WHERE nid = %d',$form['#node']->nid)),
         
'#required' => TRUE
       
);
    
$form['simplenews_alter']['simplenews_alter_company_info'] = array(
         
'#type' => 'textfield',
         
'#title' => t('Company Information'),
         
'#default_value' => db_result(db_query('SELECT company_info FROM {simplenews_alter} WHERE nid = %d',$form['#node']->nid)),
         
'#required' => TRUE
       
);
       
     return
$form;
}

/**
* @desc submit form
*/
function simplenews_alter_form_submit($form_id, &$form_values){
   
    if(
is_object($form_values)){
       
$form = get_object_vars($form_values);
    }
   
   
$nid = $form['nid'];
   
$header = $form['simplenews_alter_header'];
   
$main = $form['simplenews_alter_main'];
   
$valid_until = $form['simplenews_alter_valid_until'];
   
$price = $form['simplenews_alter_price'];
   
$company_info = $form['simplenews_alter_company_info'];
   
   
db_query("DELETE FROM {simplenews_alter} WHERE nid = %d",$nid);
   
db_query("INSERT INTO {simplenews_alter} (nid, header, main, valid_until, price, company_info)
                VALUES (%d, '%s', '%s', '%s', '%s', '%s')"
, $nid, $header, $main, $valid_until, $price, $company_info);
   
drupal_set_message(t("Extra parameters have been saved.")); 
}

/**
* @desc theme the way the newsletter is going to look, this function gets called in preview and view
*/
function theme_simplenews_alter($form_id, &$form_values){
   
   
$form = array();
    if(
is_object($form_values)){
           
$form = get_object_vars($form_values);
    }
   
    if(!
$form['op']){
   
// this generates the view
       
$message = $form['body'];
       
$result = db_query("SELECT * FROM {simplenews_alter} WHERE nid = %d",$form['nid']);
       
$elements = db_fetch_array($result);
       
       
$output =
"<table align=\"center\" cellpadding=\"5\" border=\"1\" cellspacing=\"0\" bordercolor=\"#990000\" bgcolor=\"#FFFFFF\">
<tr>
<td align=\"center\" colspan=\"2\"><img src=\"$elements[header]\"></td>
</tr>
<tr>
<td valign=\"top\" align=\"center\"><img src=\"$elements[main]\"></td><td valign=\"top\">$message</td>
</tr>
<tr>
<td align=\"center\">$elements[valid_until]</td><td>$elements[price]</td>
</tr>
<tr>
<td align=\"center\" colspan=\"2\">$elements[company_info]</td>
</tr>
</table>"
;
        return
$output;
       
             
    }else{
   
// this generates the preview 
        //drupal_set_message("theme_simplenews_alter nid: <pre>". print_r($form_values, true) . "</pre>");
       
       
$output =
"<table align=\"center\" cellpadding=\"5\" border=\"1\" cellspacing=\"0\" bordercolor=\"#990000\" bgcolor=\"#FFFFFF\">
<tr>
<td align=\"center\" colspan=\"2\"><img src=\"$form[simplenews_alter_header]\"></td>
</tr>
<tr>
<td valign=\"top\"><img src=\"$form[simplenews_alter_main]\"></td valign=\"top\"><td>$form[body]</td>
</tr>
<tr>
<td align=\"center\">$form[simplenews_alter_valid_until]</td><td align=\"center\">$form[simplenews_alter_price]</td>
</tr>
<tr>
<td align=\"center\" colspan=\"2\">$form[simplenews_alter_company_info]</td>
</tr>
</table>"
;
        return
$output;
    }
}



/**
* @desc generate the images drop down content
*/
function _simplenews_alter_images_dropdown($type){
   
$result = db_query("SELECT nid FROM node WHERE type = '$type'");
   
   
$output = array();
   
$output['select'] = 'Select an image';
    while(
$image = db_fetch_array($result)){
      
$thisnode = get_object_vars(node_load($image['nid']));
      
$output[url($thisnode["field_".$type][0]['filepath'], $query = NULL, $fragment = NULL, $absolute = TRUE)]  = $thisnode["field_".$type][0]['filepath'];
    }
   
    return
$output;    
}

/**
* @desc theme form select element
*/
function theme_simplenews_alter_select($element) {
 
$select = '';
 
$size = $element['#size'] ? ' size="' . $element['#size'] . '"' : '';
 
_form_set_class($element, array('form-select'));
 
$multiple = isset($element['#multiple']) && $element['#multiple'];
  return
theme('form_element', $element, '<select name="'. $element['#name'] .''. ($multiple ? '[]' : '') .'"'. ($multiple ? ' multiple="multiple" ' : '') . drupal_attributes($element['#attributes']) .' id="'. $element['#id'] .'" '. $size .'>'. simplenews_alter_form_select_options($element) .'</select>');
}

/**
* @desc
*/
function simplenews_alter_form_select_options($element, $choices = NULL) {
  if (!isset(
$choices)) {
   
$choices = $element['#options'];
  }
 
// array_key_exists() accommodates the rare event where $element['#value'] is NULL.
  // isset() fails in this situation.
 
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
 
$value_is_array = is_array($element['#value']);
 
$options = '';
  foreach (
$choices as $key => $choice) {
    if (
is_array($choice)) {
     
$options .= '<optgroup label="'. $key .'">';
     
$options .= simplenews_alter_form_select_options($element, $choice);
     
$options .= '</optgroup>';
    }
    elseif (
is_object($choice)) {
     
$options .= simplenews_alter_form_select_options($element, $choice->option);
    }
    else {
     
$key = (string)$key;
      if (
$value_valid && (!$value_is_array && (string)$element['#value'] === $key || ($value_is_array && in_array($key, $element['#value'])))) {
       
$selected = ' selected="selected"';
      }
      else {
       
$selected = '';
      }
     
$options .= '<option value="'. check_plain($key) .'"'. $selected .'>'. $choice .'</option>';
    }
  }
  return
$options;
}
?>

Submitted by Anonymous (not verified) on September 19, 2009 - 9:40am.

It is a good idea to use the functions already existing in the Simplenews module. a web-form with a number of options will be useful too. Have you edited or developed anything about the code? Let us know if anything is changed. Thanks for the helpful post.

Submitted by JOe (not verified) on November 27, 2009 - 10:48am.

Great idea - is there a drupal 6 version please??

Post new comment

The content of this field is kept private and will not be shown publicly.
Please solve the math question. This way we will know you are not a robot.