diff -urp mailing_list.admin.inc mailing_list.admin.inc --- mailing_list.admin.inc 2009-08-05 02:31:16.000000000 +0200 +++ mailing_list.admin.inc 2009-12-08 10:17:05.060555800 +0100 @@ -7,12 +7,30 @@ */ /** + * Constants + */ + +define('MAILING_LIST_FORM_JS', +'$(document).ready(function(){ + $("#edit-notification-email-wrapper").hide(); + //Fix visibility if notify is checked + if ($("input[name=notify]").is(":checked")) { + $("#edit-notification-email-wrapper").show(); + } + + $("input[name=notify]").change(function(){ + $("#edit-notification-email-wrapper").slideToggle(); + }); + +});'); + +/** * Menu callback; displays all mailing lists in a table. */ function mailing_list_lists() { $header = array( array('data' => t('Name'), 'field' => 'name', 'sort' => 'asc'), - array('data' => t('Operations'), 'colspan' => '5') + array('data' => t('Operations'), 'colspan' => '6') ); $query = "SELECT * FROM {mailing_list}"; @@ -20,7 +38,7 @@ function mailing_list_lists() { $rows = array(); $destination = drupal_get_destination(); while ($list = db_fetch_object($result)) { - $row = array(l(check_plain($list->name), "admin/build/mailing-list/$list->mlid"), l(t('list e-mails'), "admin/build/mailing-list/$list->mlid"), l(t('import e-mails'), "admin/build/mailing-list/$list->mlid/import", array('query' => $destination)), l(t('export list'), "admin/build/mailing-list/$list->mlid/export", array('query' => $destination)), l(t('rename list'), "admin/build/mailing-list/$list->mlid/edit", array('query' => $destination)), l(t('delete list'), "admin/build/mailing-list/$list->mlid/delete", array('query' => $destination))); + $row = array(l(check_plain($list->name), "admin/build/mailing-list/$list->mlid"), l(t('list e-mails'), "admin/build/mailing-list/$list->mlid"), l(t('import e-mails'), "admin/build/mailing-list/$list->mlid/import", array('query' => $destination)), l(t('export list'), "admin/build/mailing-list/$list->mlid/export", array('query' => $destination)), l(t('edit list'), "admin/build/mailing-list/$list->mlid/edit", array('query' => $destination)), l(t('delete list'), "admin/build/mailing-list/$list->mlid/delete", array('query' => $destination)), l(t('unsubscribe link'), "mailing-list/$list->mlid/unsubscribe", array('query' => $destination))); $rows[] = $row; } @@ -76,9 +94,10 @@ function mailing_list_emails($list = NUL } /** - * Form for adding / renaming a mailing list. + * Form for adding / editing a mailing list. */ function mailing_list_form(&$form_state, $list = null) { + drupal_add_js(MAILING_LIST_FORM_JS, 'inline'); if (empty($list)) { drupal_set_title(t('Add mailing list')); } @@ -100,6 +119,16 @@ function mailing_list_form(&$form_state, '#required' => TRUE, '#default_value'=> isset($form_state['values']['name']) ? $form_state['values']['name']: isset($list)?$list->name : '', ); + $form['notify'] = array( + '#type' => 'checkbox', + '#title' => t('Send notification when list changes'), + '#default_value' => isset($form_state['values']['notify']) ? $form_state['values']['notify']: isset($list) ? $list->notify : 0, + ); + $form['notification_email'] = array( + '#type' => 'textfield', + '#title' => t('Email Address to Receive Notification'), + '#default_value' => isset($form_state['values']['notification_email']) ? $form_state['values']['notification_email']: isset($list) ? $list->notification_email : '', + ); $form['submit'] = array( '#value' => t('Save'), '#type' => 'submit', @@ -110,24 +139,45 @@ function mailing_list_form(&$form_state, return $form; } + +/** + * Validates mailing list add / edit form + */ +function mailing_list_form_validate($form, &$form_state) { + + $notify = $form_state['values']['notify']; + $notification_email = $form_state['values']['notification_email']; + + //only check notification email if notify is set + if ($notify) { + if (!$notification_email) { + form_set_error('notification_email', t('You must provide an email address to which to send notification.')); + } + else if (!valid_email_address($notification_email)) { + form_set_error('notification_email', t("Notification must be sent to a valid email address. Please check that you've entered it correctly.")); + } + } + +} + /** - * Submit handler for the add / rename mailing list form. + * Submit handler for the add / edit mailing list form. */ function mailing_list_form_submit($form, &$form_state) { // drupal_set_message('
'. print_r($form_state['values'],1 ) . '
'); if (isset($form_state['values']['mlid'])) { - $query = "UPDATE {mailing_list} SET name = '%s' WHERE mlid = %d"; - $result = db_query($query, $form_state['values']['name'], $form_state['values']['mlid']); + $query = "UPDATE {mailing_list} SET name = '%s', notify = %d, notification_email = '%s' WHERE mlid = %d"; + $result = db_query($query, $form_state['values']['name'], $form_state['values']['notify'], $form_state['values']['notification_email'], $form_state['values']['mlid']); } else { - $query = "INSERT INTO {mailing_list} (name) VALUES ('%s')"; - $result = db_query($query, $form_state['values']['name']); + $query = "INSERT INTO {mailing_list} (name, notify, notification_email) VALUES ('%s', %d, '%s')"; + $result = db_query($query, $form_state['values']['name'], $form_state['values']['notify'], $form_state['values']['notification_email']); } if ($result) { if (isset($form_state['values']['mlid']) ) { - drupal_set_message(t('Renamed mailing list %name', array('%name' => $form_state['values']['name']))); - watchdog('mailing_list', 'Mailing list: renamed %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('view'), 'admin/build/mailing-list/'. $form_state['values']['mlid'])); + drupal_set_message(t('Edited mailing list %name', array('%name' => $form_state['values']['name']))); + watchdog('mailing_list', 'Mailing list: edited %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('view'), 'admin/build/mailing-list/'. $form_state['values']['mlid'])); } else { drupal_set_message(t('Created mailing list %name', array('%name' => $form_state['values']['name']))); diff -urp mailing_list.install mailing_list.install --- mailing_list.install 2009-08-05 02:31:16.000000000 +0200 +++ mailing_list.install 2009-12-08 10:17:05.080555800 +0100 @@ -41,6 +41,16 @@ function mailing_list_schema() { 'length' => 255, 'not null' => TRUE, ), + 'notify' => array( + 'description' => t('Whether or not notification has been requested.'), + 'type' => 'int', + 'size' => 'tiny', + ), + 'notification_email' => array( + 'description' => t('Where to send notification if requested.'), + 'type' => 'varchar', + 'length' => 255, + ), ), 'primary key' => array('mlid'), 'indexes' => array( @@ -57,10 +67,10 @@ function mailing_list_schema() { 'not null' => TRUE, ), 'mlid' => array( - 'description' => t('The {mailing_list} this e-mail belongs to.'), - 'type' => 'int', + 'description' => t('The {mailing_list} this e-mail belongs to.'), + 'type' => 'int', 'unsigned' => TRUE, - 'not null' => TRUE, + 'not null' => TRUE, 'default' => 0, ), 'mail' => array( diff -urp mailing_list.module mailing_list.module --- mailing_list.module 2009-08-05 02:31:16.000000000 +0200 +++ mailing_list.module 2009-12-08 10:23:56.999555800 +0100 @@ -19,7 +19,7 @@ function mailing_list_help($path, $arg) * Implementation of hook_perm(). */ function mailing_list_perm() { - return array('administer mailing lists'); + return array('administer mailing lists','unsubscribe from mailing lists'); } /** @@ -71,25 +71,25 @@ function mailing_list_menu() { 'file' => 'mailing_list.admin.inc', ); $items['admin/build/mailing-list/%mailing_list/import'] = array( - 'title' => t('Import e-mails'), - 'page callback' => 'drupal_get_form', + 'title' => t('Import e-mails'), + 'page callback' => 'drupal_get_form', 'page arguments' => array('mailing_list_import_form', 3), - 'access arguments' => array('administer mailing lists'), + 'access arguments' => array('administer mailing lists'), 'type' => MENU_LOCAL_TASK, 'weight' => -2, 'file' => 'mailing_list.admin.inc', - ); + ); $items['admin/build/mailing-list/%mailing_list/export'] = array( - 'title' => t('Export list'), - 'page callback' => 'mailing_list_export', - 'page arguments' => array(3), - 'access arguments' => array('administer mailing lists'), - 'type' => MENU_LOCAL_TASK, + 'title' => t('Export list'), + 'page callback' => 'mailing_list_export', + 'page arguments' => array(3), + 'access arguments' => array('administer mailing lists'), + 'type' => MENU_LOCAL_TASK, 'weight' => 0, 'file' => 'mailing_list.admin.inc', - ); - $items['admin/build/mailing-list/%mailing_list/edit'] = array( - 'title' => t('Rename list'), + ); + $items['admin/build/mailing-list/%mailing_list/edit'] = array( + 'title' => t('Edit list'), 'page callback' => 'drupal_get_form', 'page arguments' => array('mailing_list_form', 3), 'access arguments' => array('administer mailing lists'), @@ -122,6 +122,14 @@ function mailing_list_menu() { 'type' => MENU_CALLBACK, 'file' => 'mailing_list.admin.inc', ); + $items['mailing-list/%mailing_list/unsubscribe'] = array( + 'title' => 'Unsubscribe from a Mailing List', + 'title callback' => 'mailing_list_unsubscribe_title', + 'title arguments' => array(1), + 'access arguments' => array('unsubscribe from mailing lists'), + 'page callback' => 'mailing_list_unsubscribe', + 'page arguments' => array(1), + ); return $items; } @@ -184,6 +192,32 @@ function mailing_list_forms() { } /** + * Implement hook_mail() + */ +function mailing_list_mail($key, &$message, $params) { + //Get language + $language = $message['language']; + //Get standard user tokens + $tokens = user_mail_tokens($params['account'], $language); + //Mailing list specific tokens + $tokens['!list'] = $params['list']; + $tokens['!email'] = $params['email']; + + switch ($key) { + case 'subscribe': + $message['subject'] = t('!list has a new subscriber', $tokens, $language->language); + $message['body'][] = t('!list has a new subscriber:', $tokens, $language->language); + $message['body'][]= "\t" . t('!email', $tokens, $language->language); + break; + case 'unsubscribe': + $message['subject'] = t('!list unsubscribe notification', $tokens, $language->language); + $message['body'][] = t('Due to an unsubscribe request, !mail has been removed from !list', $tokens, $language->language); + break; + } +} + + +/** * Return the mailing list object matching a mailing list ID. * * @param $mlid @@ -296,8 +330,150 @@ function mailing_list_subscription_form_ if (db_query($query, $form_state['values']['mlid'], $form_state['values']['name'], $form_state['values']['mail'])) { drupal_set_message(t('Subscription for %mail saved.', array('%mail' => $form_state['values']['mail']))); watchdog('mailing_list', 'Mailing list: %name added via subscription form.', array('%name' => $form_state['values']['mail'])); + //Send notification + mailing_list_notify($form_state['values']['mail'], $form_state['values']['mlid']); } else { drupal_set_message(t('Failed to subscribe to mailing list %name.', array('%name' => $form_state['values']['ml_name'])), 'error'); } } + +/** + * Unsubscribe functions + */ + +/** + * Generates unsubscribe page + */ +function mailing_list_unsubscribe($list) { + + //check that the list exists + if ($list) { + return drupal_get_form('mailing_list_unsubscribe_form', $list); + } + else { + drupal_set_message(t("You're trying to unsubscribe from a mailing list that doesn't exist."), 'error'); + } + +} + +/** + * Generates unsubscribe page title + */ +function mailing_list_unsubscribe_title($list) { + return t('Unsubscribe from !list', array('!list' => $list->name)); +} + +/** + * FAPI definition of unsubscribe form + * + * @see mailing_list_unsubscribe_form_validate() + * @see mailing_list_unsubscribe_form_submit() + */ +function mailing_list_unsubscribe_form($form_state, $list){ + + $form = array(); + + $form['mlid'] = array( + '#type' => 'hidden', + '#default_value' => $list->mlid, + ); + + $form['name'] = array( + '#type' => 'hidden', + '#value' => $list->name, + ); + + $form['email'] = array( + '#title' => t('Email'), + '#type' => 'textfield', + '#description' => t('Please enter the email address you would like to unsubscribe from @list', array('@list' => $list->name)), + '#size' => 15, + '#default_value' => $form_state['values']['email'], + ); + + $form['submit'] = array( + '#value' => t('Unsubscribe'), + '#type' => 'submit', + ); + + return $form; + +} + +/** + * Validates mailing list unsubscribe form + */ +function mailing_list_unsubscribe_form_validate($form, &$form_state) { + + $email = $form_state['values']['email']; + $mlid = $form_state['values']['mlid']; + + //Validate email address + if (!valid_email_address($email)) { + form_set_error('email',t('Email is not valid, please check that you have entered it correctly.')); + } + + //Check that email address is subscribed + $query = "SELECT * FROM {mailing_list_emails} WHERE mlid='%d' AND mail='%s'"; + $result = db_query($query, $mlid, $email); + + if (!db_fetch_object($result)) { + form_set_error('email', t("This email address isn't subscribed to the mailing list. Maybe you already unsubscribed? Check that you entered your email address correctly. If so, and if you continue to receive unwanted email, please contact the site administrators.")); + } + +} + +/** + * Removes unsubscribed email address from mailing list + */ +function mailing_list_unsubscribe_form_submit($form, &$form_state) { + + $mlid = $form_state['values']['mlid']; + $email = $form_state['values']['email']; + $name = $form_state['values']['name']; + + $query = "DELETE FROM {mailing_list_emails} WHERE mlid=%d AND mail='%s'"; + + if (db_query($query, $mlid, $email)) { + drupal_set_message(t('You have been successfully unsubscribed from %list', array('%list' => $name))); + watchdog('mailing_list', 'Mailing list: %email removed via unsubscribe form.', array('%email' => $form_state['values']['email'])); + //send notification + mailing_list_notify($email, $mlid, 1); + + } + else { + drupal_set_message(t('Failed to unsubscribe to %list, please contact site administrators.', array('%list' => $name)), 'error'); + } + +} + +/** + * Sends notification on (un)subscription to a mailing list + * + * @param $email + * the email address added + * @param $mlid + * the primary key of the mailing list + * @param $unsubscribe + * boolean; if it evaluates to true, + * an unsubscribe notification is sent. + */ +function mailing_list_notify($email, $mlid, $unsubscribe = 0) { + $query = "SELECT * FROM {mailing_list} WHERE mlid = %d"; + $result = db_fetch_object(db_query($query, $id)); + + //Check if notification is required + if ($result->notify && $result->notification_email) { + $to = $result->notification_email; + $language = language_default(); + $params = array( + 'list' => $result->name, + 'email' => $email, + ); + + if ($unsubscribe) drupal_mail('mailing_list', 'unsubscribe', $to, $language, $params, NULL, TRUE); + else drupal_mail('mailing_list', 'subscribe', $to, $language, $params, NULL, TRUE); + + } +} \ No newline at end of file