array('name' => t('newsletter'), 'base' => 'simplenews')); } /** * Valid permissions for this module */ function simplenews_perm() { return array('view links in block', 'create newsletter', 'edit own newsletter', 'administer newsletters', 'send newsletter', 'subscribe to newsletters'); } /** * Implementation of hook_access(). */ function simplenews_access($op, $node) { global $user; if ($op == 'create') { if (user_access('create newsletter') || user_access('administer newsletters')) { return TRUE; } } if ($op == 'update' || $op == 'delete') { if (user_access('administer newsletters')) { return TRUE; } elseif (user_access('edit own newsletter') && ($user->uid == $node->uid)) { return TRUE; } } } /** * Implementation of hook_menu(). */ function simplenews_menu($may_cache) { theme_add_style(drupal_get_path('module', 'simplenews').'/simplenews.css'); //process subscriptions submitted through blocks before page content is processed $result = db_query("SELECT DISTINCT(delta) FROM {blocks} WHERE module = '%s' AND status = %d", 'simplenews', 1); while ($delta = db_fetch_object($result)) { list($type, $tid) = explode('-', $delta->delta); if ($_POST['sn_'.$tid] && user_access('subscribe to newsletters')) { $edit = $_POST['edit']; simplenews_process_subscription($tid, $edit['sn_email_'.$tid], $edit['sn_subscribe_'.$tid]); } } $items = array(); if ($may_cache) { $items[] = array('path' => 'node/add/simplenews', 'title' => t('newsletter'), 'access' => user_access('create newsletter')); $items[] = array('path' => 'admin/newsletter', 'title' => t('newsletters'), 'access' => user_access('administer newsletters'), 'callback' => 'simplenews_admin'); $items[] = array('path' => 'admin/newsletter/sent', 'title' => t('sent items'), 'access' => user_access('administer newsletters'), 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10); $items[] = array('path' => 'admin/newsletter/outbox', 'title' => t('drafts'), 'access' => user_access('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'weight' => -9); $items[] = array('path' => 'admin/newsletter/types', 'title' => t('newsletters'), 'access' => user_access('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'weight' => -8); $items[] = array('path' => 'admin/newsletter/types/list', 'title' => t('list newsletters'), 'access' => user_access('administer newsletters'), 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10); $items[] = array('path' => 'admin/newsletter/types/add', 'title' => t('add newsletter'), 'access' => user_access('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'weight' => -9); $items[] = array('path' => 'admin/newsletter/users', 'title' => t('subscriptions'), 'access' => user_access('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'weight' => -7); $items[] = array('path' => 'admin/newsletter/users/list', 'title' => t('list subscriptions'), 'access' => user_access('administer newsletters'), 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10); $items[] = array('path' => 'admin/newsletter/users/add', 'title' => t('import subscriptions'), 'access' => user_access('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'weight' => -9); $items[] = array('path' => 'admin/newsletter/users/export', 'title' => t('export subscriptions'), 'access' => user_access('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'weight' => -8); $items[] = array('path' => 'admin/newsletter/settings', 'title' => t('settings'), 'access' => user_access('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'weight' => -6); $items[] = array('path' => 'admin/newsletter/settings/general', 'title' => t('general'), 'access' => user_access('administer newsletters'), 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10); $items[] = array('path' => 'newsletter/confirm', 'title' => t('confirm newsletter subscriptions'), 'access' => user_access('access content'), 'callback' => 'simplenews_confirm_subscription', 'type' => MENU_CALLBACK); $items[] = array('path' => 'newsletter/subscriptions', 'title' => t('manage newsletter subscriptions'), 'access' => user_access('subscribe to newsletters'), 'callback' => 'simplenews_subscription_manager_page', 'type' => MENU_CALLBACK); } else { $tree = taxonomy_get_tree(simplenews_get_vid()); if ($tree) { $i = -9; foreach ($tree as $newsletter) { $items[] = array('path' => 'admin/newsletter/settings/'.$newsletter->tid, 'title' => $newsletter->name, 'access' => user_access('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'weight' => $i); $i++; } } } return $items; } /** * Implementation of hook_form(). */ function simplenews_form(&$node) { simplenews_create_taxonomy(); global $user; $form['title'] = array( '#type' => 'textfield', '#title' => t('Title'), '#default_value' => $node->title, '#size' => 60, '#maxlength' => 128, '#required' => TRUE, ); $form['body'] = array( '#type' => 'textarea', '#title' => t('Message'), '#default_value' => $node->body, '#rows' => 20, '#required' => TRUE, '#description' => t('This will be the body of your newsletter. Available variables are:') . ' %site ' . t('(the name of your website),') . ' %uri ' . t('(a link to your homepage),') . ' %uri_brief ' . t('(homepage link without the http://),') . ' %mymail ' . t('(your e-mail address),') . ' %date ' . t('(today\'s date),') . ' %login_uri ' . t('(link to login page).'), ); $form['format'] = filter_form($node->format); if (!$sel1 = $node->s_format) { $sel1 = variable_get('simplenews_format', 'plain'); } if (!$sel2 = $node->priority) { $sel2 = variable_get('simplenews_priority', 0); } if (!$sel3 = $node->receipt) { $sel3 = variable_get('simplenews_receipt', 0); } $form['sending_options'] = array( '#type' => 'fieldset', '#title' => t('Newsletter sending options'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['sending_options']['s_format'] = array( '#type' => 'select', '#title' => t('Format'), '#default_value' => $sel1, '#options' => array('plain' => t('plain'), 'html' => t('html')), ); $form['sending_options']['priority'] = array( '#type' => 'select', '#title' => t('Priority'), '#default_value' => $sel2, '#options' => array(0 => t('none'), 1 => t('highest'), 2 => t('high'), 3 => t('normal'), 4 => t('low'), 5 => t('lowest')), ); $form['sending_options']['receipt'] = array( '#type' => 'checkbox', '#title' => t('Request receipt'), '#return_value' => 1, '#default_value' => $sel3, ); if ($node->s_status == 0) { if (user_access('send newsletter')) { $options[0] = t("Don't send now"); $options[2] = t('Send one test newsletter to the test address'); $options[1] = t('Send newsletter'); $form['sending_options']['send'] = array( '#type' => 'radios', '#title' => t('Sending'), '#default_value' => $node->send ? $node->send : variable_get('simplenews_send', 0), '#options' => $options, ); } else { $options[0] = t("Don't send now"); $options[2] = t('Send one test newsletter to the test address'); $form['sending_options']['send'] = array( '#type' => 'radios', '#title' => t('Sending'), '#default_value' => $node->send ? $node->send : 0, '#options' => $options, '#description' => t('You have no privileges to send this newsletter'), ); } if (variable_get('simplenews_test_address_override', 0)) { $form['sending_options']['test_address'] = array( '#type' => 'textfield', '#title' => t('Test e-mail addresses'), '#default_value' => $node->test_address ? $node->test_address : variable_get('simplenews_test_address', ''), '#size' => 60, '#maxlength' => 128, ); $form['sending_options']['#description'] = t('Supply a comma-separated list of e-mail addresses to be used as test addresses.'); } } else { $atts = array('disabled'=>'disabled'); $form['sending_options']['none'] = array( '#type' => 'checkbox', '#title' => t('This newsletter has been sent'), '#return_value' => 0, '#attributes' => array('checked' => 'checked', 'disabled' => 'disabled'), ); } $form['s_status'] = array( '#type' => 'hidden', '#value' => $node->s_status ? $node->s_status : 0, ); return $form; } /** * Implementation of hook_validate(). */ function simplenews_validate($node) { global $valid_mails; if ($node->taxonomy && $node->send == 1) { if (!simplenews_validate_taxonomy($node->taxonomy)) { form_set_error('', t('You should select a newsletter if you want to send this newsletter.')); } } if ($node->send == 2) { if (variable_get('simplenews_test_address_override', 0)) { $mails = explode(',',$node->test_address); } else { $mails = explode(',',variable_get('simplenews_test_address', '')); } foreach ($mails as $mail) { $mail = trim($mail); if ($mail == '') { form_set_error('', t('Cannot send test newsletter: no valid test e-mail address specified.')); } elseif (!valid_email_address($mail)) { form_set_error('', t('Cannot send test newsletter to %mail: e-mail address invalid.', array('%mail'=>theme('placeholder',$mail)))); } else { $valid_mails[] = $mail; } } } } /** * Implementation of hook_submit(). */ function simplenews_submit(&$node) { global $valid_mails; if ($node->send == 2 && $valid_mails) { $node->test_address = $valid_mails; } } function simplenews_validate_taxonomy($taxonomy) { $vid = simplenews_get_vid(); $result = db_query('SELECT tid FROM {term_data} WHERE vid = %d', $vid); while ($tid = db_fetch_object($result)) { $tids[] = $tid->tid; } $taxes = array(); foreach ($taxonomy as $tax) { $taxes[] = $tax; } return array_intersect($tids, $taxes); } /** * Implementation of hook_cron(). */ function simplenews_cron() { _sn_send(FALSE); } /** * Implementation of hook_insert(). * Saves extra node content to module database table * and sends the newsletter, upon node creation */ function simplenews_insert($node) { $term = simplenews_validate_taxonomy($node->taxonomy); $tid = is_array($term) ? array_values($term) : FALSE; $node->sn_tid = $tid ? $tid[0] : 0; //tid is also saved in this table since it is needed by _sn_send(), and the term_node table is //only updated after the execution of simplenews_insert(). It cannot be passed by a variable //since simplenews_cron() also calls _sn_send(). if ($node->send == 1 && user_access('send newsletter')) { db_query("INSERT INTO {sn_newsletters} (nid, tid, s_status, s_format, priority, receipt) VALUES (%d, %d, %d, '%s', %d, %d)", $node->nid, $node->sn_tid, 1, $node->s_format, $node->priority, $node->receipt); _sn_send(TRUE); drupal_set_message(t('Newsletter %newsletter is being sent', array('%newsletter' => theme('placeholder', $node->title)))); } else { db_query("INSERT INTO {sn_newsletters} (nid, tid, s_status, s_format, priority, receipt) VALUES (%d, %d, %d, '%s', %d, %d)", $node->nid, $node->sn_tid, 0, $node->s_format, $node->priority, $node->receipt); } if ($node->send == 2) { simplenews_send_test($node); } } /** * Implementation of hook_update(). */ function simplenews_update($node) { $term = simplenews_validate_taxonomy($node->taxonomy); $tid = is_array($term) ? array_values($term) : FALSE; $node->sn_tid = $tid ? $tid[0] : 0; if ($node->send == 1 && user_access('send newsletter')) { db_query("UPDATE {sn_newsletters} SET tid = %d, s_status = %d, s_format = '%s', priority = %d, receipt = %d WHERE nid = %d", $node->sn_tid, 1, $node->s_format, $node->priority, $node->receipt, $node->nid); _sn_send(TRUE); drupal_set_message(t('Newsletter %newsletter is being sent', array('%newsletter' => theme('placeholder', $node->title)))); } else { db_query("UPDATE {sn_newsletters} SET tid = %d, s_format = '%s', priority = %d, receipt = %d WHERE nid = %d", $node->sn_tid, $node->s_format, $node->priority, $node->receipt, $node->nid); } if ($node->send == 2) { simplenews_send_test($node); } } /** * Implementation of hook_delete(). */ function simplenews_delete($node) { global $user; $result = db_query('DELETE FROM {sn_newsletters} WHERE nid = %d', $node->nid); if ($result) { drupal_set_message(t('Newsletter %title was successfully deleted.', array('%title'=>theme('placeholder', $node->title)))); } } /** * Implementation of hook_load(). */ function simplenews_load($node) { $additions = db_fetch_object(db_query('SELECT * FROM {sn_newsletters} WHERE nid = %d', $node->nid)); return $additions; } /** * Implementation of hook_taxonomy(). * Deletes subscriptions to term when term is deleted, and cleans the blocks table */ function simplenews_taxonomy($op, $type, $object = NULL) { if ($type == 'term' && $op == 'delete' && $object->vid == simplenews_get_vid()) { db_query('DELETE FROM {sn_snid_tid} WHERE tid = %d', $object->tid); db_query("DELETE FROM {blocks} WHERE module = '%s' AND delta = '%s'", 'simplenews', 'newsletter-'.$object->tid); drupal_set_message(t('Deleted all subscriptions to newsletter %newsletter.', array('%newsletter'=>theme('placeholder', $object->name)))); } elseif ($op == 'delete' && $type == 'vocabulary' && $object->vid == simplenews_get_vid()) { variable_del('simplenews_vid'); } } /** * Implementation of hook_view(). */ function simplenews_view(&$node, $teaser = FALSE) { $node = simplenews_replace_vars($node, TRUE); $node = node_prepare($node, $teaser); } /** * Implementation of hook_user() * Checks whether an email address is subscribed to the newsletter * when a new user signs up. If so, changes uid from 0 to the new uid * in sn_subscriptions so that the user's subscription status is known * when he logs in. */ function simplenews_user($op, &$edit, &$account, $category = NULL) { switch ($op) { case 'insert': if ($edit['mail']) { $query = "SELECT snid FROM {sn_subscriptions} WHERE mail = '%s'"; if ($result = db_fetch_object(db_query($query, $edit['mail']))) { db_query("UPDATE {sn_subscriptions} SET uid = %d WHERE snid = %d", $edit['uid'], $result->snid); } } break; case 'update': if ($category == 'account' && $edit['mail']) { $query = "SELECT snid FROM {sn_subscriptions} WHERE uid = %d"; if ($result = db_fetch_object(db_query($query, $account->uid))) { db_query("DELETE FROM {sn_subscriptions} WHERE mail = '%s' AND uid = %d", $edit['mail'], 0); db_query("UPDATE {sn_subscriptions} SET mail = '%s' WHERE snid = %d", $edit['mail'], $result->snid); } else { $query = "SELECT snid FROM {sn_subscriptions} WHERE mail = '%s'"; if ($result = db_fetch_object(db_query($query, $edit['mail']))) { db_query("UPDATE {sn_subscriptions} SET uid = %d WHERE snid = %d", $account->uid, $result->snid); } } } elseif ($category == 'newsletter' && user_access('subscribe to newsletters')) { _simplenews_subscription_manager(FALSE, FALSE, TRUE); } break; case 'delete': $query = "SELECT snid FROM {sn_subscriptions} WHERE uid = %d"; if ($result = db_fetch_object(db_query($query, $account->uid))) { db_query("UPDATE {sn_subscriptions} SET uid = %d WHERE snid = %d", 0, $result->snid); } break; case 'form': if ($category == 'newsletter' && user_access('subscribe to newsletters')) { $form['newsletters'] = _simplenews_subscription_manager($account); $form['newsletters']['#title'] = t('Current newsletter subscriptions'); $form['newsletters']['sn_email'] = array( '#type' => 'hidden', '#value' => $account->mail, ); $form['newsletters']['sn_update'] = array( '#type' => 'hidden', '#value' => 'Update', ); return $form; } break; case 'categories': if (user_access('subscribe to newsletters')) { $output[] = array('name' => 'newsletter', 'title' => t('my newsletters'), 'weight' => 10); } return $output; break; case 'view': global $user; if ($user->uid == $account->uid || user_access('administer users')) { $tree = taxonomy_get_tree(simplenews_get_vid()); foreach ($tree as $newsletter) { if (db_num_rows(db_query('SELECT s.uid FROM {sn_subscriptions} s INNER JOIN {sn_snid_tid} t ON s.snid = t.snid WHERE s.uid = %d AND t.tid = %d', $account->uid, $newsletter->tid))) { $subscriptions[] = l($newsletter->name, 'taxonomy/term/'. $newsletter->tid); } } if ($subscriptions) { $subscriptions = implode(', ', $subscriptions); } else { $subscriptions = t('Currently no subscriptions'); } $items[] = array( 'class' => 'item', 'title' => t('Current subcriptions'), 'value' => $subscriptions, ); $items[] = array( 'class' => 'item', 'title' => t('Manage subscriptions'), 'value' => l(t('my newsletters'), 'user/'. $account->uid .'/edit/newsletter'), ); return array(t('Newsletters') => $items); } break; } } /** * Implementation of hook_block() */ function simplenews_block($op='list', $delta=0) { if ($op == 'list') { $tree = taxonomy_get_tree(simplenews_get_vid()); if ($tree) { foreach ($tree as $newsletter) { $block['newsletter-'.$newsletter->tid]['info'] = t('Newsletter: %title', array('%title' => theme('placeholder', $newsletter->name))); } } return $block; } elseif ($op == 'view') { list($type, $tid) = explode('-', $delta); if ($type == 'newsletter') { if ($newsletter = taxonomy_get_term($tid)) { if (variable_get('simplenews_block_m_status_'.$tid, 1)) { $message = '
'; $message .= variable_get('simplenews_block_m_'.$tid, t('Stay informed on our latest news!')); $message .= '
'; } else { $message = NULL; } $block['subject'] = check_plain($newsletter->name); if (variable_get('simplenews_block_f_'.$tid, 1) && user_access('subscribe to newsletters')) { $block['content'] = _sn_block($message, $tid); } else { if ($message) { $block['content'] = $message; } if (user_access('subscribe to newsletters')) { $block['content'] .= l(t('Manage my subscriptions'), 'newsletter/subscriptions/'); } } } if (user_access('view links in block') || user_access('administer newsletters')) { if (variable_get('simplenews_block_l_'.$tid, 1)) { $block['content'] .= theme('sn_term_link', l(t('Previous issues'), 'taxonomy/term/'.$tid)); } elseif (variable_get('simplenews_block_i_status_'.$tid, 0)) { $block['content'] .= theme('sn_term_link', t('Previous issues')); } if (variable_get('simplenews_block_i_status_'.$tid, 0)) { $block['content'] .= _simplenews_recent_newsletters($tid, variable_get('simplenews_block_i_'.$tid, 5)); } if (variable_get('simplenews_block_r_'.$tid, 1)) { $block['content'] .= theme('sn_feed_icon', url('taxonomy/term/'.$tid.'/0/feed')); } } } return $block; } } function simplenews_handle_messages($one, $two_or_more, $type = 'status') { if (isset($_SESSION['messages'][$type])) $msg = $_SESSION['messages'][$type]; else $msg = array(); $key = array_search($one, $msg); if ($key || $key === 0) { $_SESSION['messages'][$type][$key] = $two_or_more; } elseif (!in_array($two_or_more, $msg)) { drupal_set_message($one, $type); } } function simplenews_process_subscription($tid, $mail, $sub) { global $user; //valid_email_address() allows empty address, so check this first if ($mail == '') { simplenews_handle_messages(t('You have to supply an e-mail address'), t('You have to supply an e-mail address'), 'error'); } elseif (!valid_email_address($mail)) { simplenews_handle_messages(t('The e-mail address you supplied is not valid'), t('The e-mail address you supplied is not valid'), 'error'); } else { global $base_url; $snid_result = db_query("SELECT snid FROM {sn_subscriptions} WHERE mail = '%s'", $mail); $snid_obj = db_fetch_object($snid_result); $name_default = variable_get('site_name', 'drupal'); $newsletter = taxonomy_get_term($tid); if ($sub == 'Subscribe') { if (!db_num_rows($snid_result)) { $query = "SELECT uid FROM {users} WHERE mail = '%s'"; if ($result = db_fetch_object(db_query($query, $mail))) { $uid = $result->uid; } else { $uid = 0; } db_query("INSERT INTO {sn_subscriptions} (mail, uid, a_status) VALUES ('%s', %d, %d)", $mail, $uid, 1); $snid_result = db_query("SELECT snid FROM {sn_subscriptions} WHERE mail = '%s'", $mail); $snid_obj = db_fetch_object($snid_result); $watchdog = t('User %email added to the database.', array('%email'=>theme('placeholder',$mail))); watchdog('newsletter', $watchdog); } if ($user->uid == 0) { //send confirmation email: "Confirm subscription" $body = t('We have received a request for subscription of your e-mail address, %mail, to the "%newsletter" newsletter from %site (%uri). To confirm that you want to be added to this mailing list, simply visit the confirmation link at the bottom of this e-mail.', array('%mail'=>$mail, '%newsletter'=>$newsletter->name, '%site'=>variable_get('simplenews_from_name', $name_default), '%uri'=>$base_url)); $body .= "\n\n".t('If you do not wish to be subscribed to this list, please disregard this message.'); sn_mail_confirm($mail, $body, $newsletter->name, $snid_obj->snid, $tid, 'subscribe'); simplenews_handle_messages(t('You will receive a confirmation e-mail shortly.'), t('You will receive confirmation e-mails shortly.')); } else { $snid_tid = db_query("SELECT snid FROM {sn_snid_tid} WHERE snid = %d AND tid = %d", $snid_obj->snid, $tid); if (!db_num_rows($snid_tid)) { db_query("INSERT INTO {sn_snid_tid} (snid, tid) VALUES (%d, %d)", $snid_obj->snid, $tid); } simplenews_handle_messages(t('The newsletter subscriptions have been updated.'), t('The newsletter subscriptions have been updated.')); } } elseif ($sub == 'Unsubscribe') { if ($user->uid == 0) { $snid_tid = db_query("SELECT snid FROM {sn_snid_tid} WHERE snid = %d AND tid = %d", $snid_obj->snid, $tid); if (db_num_rows($snid_result) && db_num_rows($snid_tid)) { //send confirmation email: "Confirm deletion" $body = t('We have received a request for the removal of your e-mail address, %mail, from the "%newsletter" newsletter from %site (%uri). If you want to unsubscribe, simply visit the confirmation link at the bottom of this e-mail.', array('%mail'=>$mail, '%newsletter'=>$newsletter->name, '%site'=>variable_get('simplenews_from_name', $name_default), '%uri'=>$base_url)); $body .= "\n\n".t('If you do not wish to be removed from this list, please disregard this message.'); sn_mail_confirm($mail, $body, $newsletter->name, $snid_obj->snid, $tid, 'unsubscribe'); } else { //send confirmation email: "You were not subscribed. Visit site to subscribe." $body = t('We have received a request for the removal of your e-mail address, %mail, from the "%newsletter" newsletter from %site (%uri). However, you were not subscribed to this newsletter. If you want to subscribe, you can visit our website by using the link at the bottom of this e-mail.', array('%mail'=>$mail, '%newsletter'=>$newsletter->name, '%site'=>variable_get('simplenews_from_name', $name_default), '%uri'=>$base_url)); $body .= "\n\n".t('If you do not wish to be subscribed to this list, please disregard this message.'); sn_mail_confirm($mail, $body, $newsletter->name); } simplenews_handle_messages(t('You will receive a confirmation e-mail shortly.'), t('You will receive confirmation e-mails shortly.')); } else { if (db_num_rows($snid_result)) { $query = "DELETE FROM {sn_snid_tid} WHERE snid = %d AND tid = %d"; if (db_affected_rows(db_query($query, $snid_obj->snid, $tid))) { simplenews_handle_messages(t('Your newsletter subscriptions have been updated.'), t('Your newsletter subscriptions have been updated.')); } //Perform db cleanup tasks if (!db_num_rows(db_query('SELECT tid FROM {sn_snid_tid} WHERE snid = %d', $snid_obj->snid))) { db_query('DELETE FROM {sn_subscriptions} WHERE snid = %d', $snid_obj->snid); $watchdog = t('User %email deleted from the database.', array('%email'=>theme('placeholder', $mail))); watchdog('newsletter', $watchdog); } } } } } } function simplenews_subscription_manager() { print _simplenews_subscription_manager(); } function simplenews_subscription_manager_page() { if (user_access('subscribe to newsletters')) { global $user; if ($user->uid == 0) { return _simplenews_subscription_manager(); } else { drupal_goto('user/'.$user->uid.'/edit/newsletter'); } } else { drupal_goto(); } } function _simplenews_subscription_manager($account = FALSE, $snid = FALSE, $pre_process_only = FALSE) { if (user_access('subscribe to newsletters')) { if ($account) $user = $account; else global $user; $tree = taxonomy_get_tree(simplenews_get_vid()); $edit = $_POST['edit']; if ($_POST['sn_subscribe'] || $_POST['sn_unsubscribe']) { if ($tree) { if ($_POST['sn_subscribe'] == t('Subscribe')) $sub = 'Subscribe'; if ($_POST['sn_unsubscribe'] == t('Unsubscribe')) $sub = 'Unsubscribe'; $selected = FALSE; foreach ($tree as $newsletter) { if ($edit['sn_'.$newsletter->tid] == 1) { simplenews_process_subscription($newsletter->tid, $edit['sn_email'], $sub); $selected = TRUE; } } } if (!$selected) drupal_set_message(t('You should select at least one newsletter.'), 'error'); } elseif ($_POST['sn_update'] || $edit['sn_update']) { if ($tree) { foreach ($tree as $newsletter) { if ($edit['sn_'.$newsletter->tid] == 1) { simplenews_process_subscription($newsletter->tid, $edit['sn_email'], 'Subscribe'); } else { simplenews_process_subscription($newsletter->tid, $edit['sn_email'], 'Unsubscribe'); } } } } if ($pre_process_only) return; if ($snid && $_POST['sn_update']) drupal_goto('admin/newsletter/users'); $output = '
'; if ($tree) { foreach ($tree as $newsletter) { if ($user->uid == 0) { $checked = 0; } else { if ($snid) { $result = db_query("SELECT s.snid FROM {sn_subscriptions} s INNER JOIN {sn_snid_tid} t ON s.snid = t.snid WHERE t.tid = %d AND s.snid = %d", $newsletter->tid, $snid); } else { $result = db_query("SELECT s.snid FROM {sn_subscriptions} s INNER JOIN {sn_snid_tid} t ON s.snid = t.snid WHERE t.tid = %d AND s.uid = %d", $newsletter->tid, $user->uid); } if (db_num_rows($result)) { $checked = 1; } else $checked = 0; } $form['newsletters']['#type'] = 'fieldset'; $form['newsletters']['#weight'] = 1; $form['newsletters']['sn_'.$newsletter->tid] = array( '#type' => 'checkbox', '#title' => $newsletter->name, '#return_value' => 1, '#attributes' => $checked ? array('checked' => 'checked') : NULL, ); } if ($account) return $form['newsletters']; if ($user->uid == 0) { $form['sn_email'] = array( '#type' => 'textfield', '#title' => t('E-mail'), '#size' => 20, '#maxlength' => 128, '#weight' => -20, ); $form['newsletters']['#title'] = t('Available newsletters'); $form['newsletters']['#description'] = t('Select the newsletter(s) to which you want to subscribe or unsubscribe.'); $form['sn_subscribe'] = array( '#name' => 'sn_subscribe', '#type' => 'submit', '#value' => t('Subscribe'), '#weight' => 19, ); $form['sn_unsubscribe'] = array( '#name' => 'sn_unsubscribe', '#type' => 'submit', '#value' => t('Unsubscribe'), '#weight' => 20, ); } else { if ($snid) { $result = db_query("SELECT mail FROM {sn_subscriptions} WHERE snid = %d", $snid); $sn_email = db_result($result); $message = t('Subscriptions for %mail', array('%mail'=>theme('placeholder', $sn_email))); $explanation = ''; } else { $sn_email = $user->mail; $message = t('Available newsletters'); $explanation = t('Select the newsletter(s) to which you want to be subscribed.'); } $form['sn_email'] = array( '#type' => 'hidden', '#value' => $sn_email, ); $form['newsletters']['#title'] = $message; $form['newsletters']['#description'] = $explanation; $form['sn_update'] = array( '#type' => 'submit', '#name' => 'sn_update', '#value' => t('Update'), '#weight' => 20, ); } } $output .= drupal_get_form('_simplenews_subscription_manager', $form); $output .= '
'; return $output; } else { return ''; } } // Todo: use node_title_list() instead? Disadvantage: not separately themable? function _simplenews_recent_newsletters($tid, $count = 5, $title = NULL) { $result = db_query_range(db_rewrite_sql('SELECT n.nid, n.title, n.created FROM {node} n INNER JOIN {term_node} t ON n.nid = t.nid INNER JOIN {sn_newsletters} sn ON n.nid = sn.nid WHERE (t.tid = %d AND n.status = 1 AND sn.s_status > 0) ORDER BY n.created DESC'), $tid, 0, $count); while ($item = db_fetch_object($result)) { $titles[] = l($item->title, 'node/'.$item->nid); } if ($titles) { return theme('sn_item_list', $titles, $title); } } function simplenews_recent_newsletters($tid, $count = 5, $title = NULL) { print _simplenews_recent_newsletters($tid, $count, $title); } /** * Prepare the block subscription form */ function theme_sn_form($tid, $sub=1, $unsub=1, $email='') { $sn_form = '
'; if ($sub == 1 && $unsub == 1) { $form['sn_email_'.$tid] = array( '#type' => 'textfield', '#title' => t('E-mail'), '#size' => 20, '#maxlength' => 128, ); $options = array(); $options['Subscribe'] = t('Subscribe'); $options['Unsubscribe'] = t('Unsubscribe'); $form['sn_subscribe_'.$tid] = array( '#type' => 'radios', '#default_value' => 'Subscribe', '#options' => $options, ); $submit = t('Submit'); } else { $sn_form .= '

'; $sn_form .= truncate_utf8($email, 29, FALSE, TRUE); $sn_form .= '
'; $form['sn_email_'.$tid] = array( '#type' => 'hidden', '#value' => $email, ); if ($sub == 1) { $form['sn_subscribe_'.$tid] = array( '#type' => 'hidden', '#value' => 'Subscribe', ); $submit = t('Subscribe'); } elseif ($unsub == 1) { $form['sn_subscribe_'.$tid] = array( '#type' => 'hidden', '#value' => 'Unsubscribe', ); $submit = t('Unsubscribe'); } } $form['sn_'.$tid] = array( '#name' => 'sn_'.$tid, '#type' => 'submit', '#value' => $submit, ); $sn_form .= drupal_get_form('theme_sn_form', $form); $sn_form .= '
'; return $sn_form; } /** * Prepare block content */ function _sn_block($message, $tid) { global $user; if ($message) { $block_content = $message; } if ($user->uid == 0) { $block_content .= theme('sn_form', $tid, 1, 1); } else { $query = 'SELECT s.snid FROM {sn_subscriptions} s INNER JOIN {sn_snid_tid} t ON s.snid = t.snid WHERE s.uid = %d AND t.tid = %d'; if (db_num_rows(db_query($query, $user->uid, $tid))) { $block_content .= theme('sn_form', $tid, 0, 1, $user->mail); } else { $block_content .= theme('sn_form', $tid, 1, 0, $user->mail); } } return $block_content; } /** * Prepare node for sending */ function simplenews_node_prepare($nid, $tid) { $node = node_load(array('nid' => $nid), NULL, TRUE); $node = simplenews_replace_vars($node, FALSE); $node = node_prepare($node); $node->body = '

'.$node->title.'

'."\n".$node->body; if ($node->s_format == 'plain') { $node->body = sn_html_to_text($node->body, variable_get('simplenews_hyperlinks_'.$tid, 1)); } else { $pattern = '@(]*>)@ei'; $node->body = preg_replace($pattern, "'\\1' . '\"' . _sn_mail_url('\\2') . '\"' . '\\3'", $node->body); } $address_default = variable_get('site_mail', ini_get('sendmail_from')); $name_default = variable_get('site_name', 'drupal'); if ($tid) { $node->from_address = variable_get('simplenews_from_address_'.$tid, $address_default); $node->from_name = variable_get('simplenews_from_name_'.$tid, $name_default); } else { $node->from_address = variable_get('simplenews_from_address', $address_default); $node->from_name = variable_get('simplenews_from_name', $name_default); } return $node; } /** * Send the newsletter */ function _sn_send($timer = FALSE) { $max_time = variable_get('simplenews_time', 5); if ($timer && $max_time == 0) { return; } if ($max_time == 0) { $max_time = 1; } $max_time = $max_time - 0.5; $start_time = sn_time(); if (!$timer) { $throttle = variable_get('simplenews_throttle', 20); static $counter = 0; } $result = db_query(db_rewrite_sql('SELECT n.nid, s.tid, n.created FROM {node} n INNER JOIN {sn_newsletters} s ON n.nid = s.nid WHERE s.s_status = %d ORDER BY n.created ASC'), 1); while ($nid = db_fetch_object($result)) { $term = taxonomy_get_term($nid->tid); $node = simplenews_node_prepare($nid->nid, $nid->tid); $node->title = "[$term->name] ".$node->title; $result2 = db_query('SELECT s.mail, s.snid FROM {sn_subscriptions} s INNER JOIN {sn_snid_tid} t ON s.snid = t.snid WHERE s.s_status = %d AND s.a_status = %d AND t.tid = %d ORDER BY s.snid ASC', 0, 1, $nid->tid); while ($mail = db_fetch_object($result2)) { $md5 = md5($mail->mail . simplenews_private_key()); $h = drupal_substr($md5, 0, 10).$mail->snid.'t'.$nid->tid; if ($node->s_format == 'html') { $node->message = $node->body.'

--
'.l(t('Click here to unsubscribe from this newsletter'), 'newsletter/confirm/remove/'.$h, array(), NULL, NULL, TRUE).'

'; } else { $node->message = $node->body."\n\n--\n".t('Unsubscribe from this newsletter:').' '.url('newsletter/confirm/remove/'.$h, NULL, NULL, TRUE); } $node->to = $mail->mail; if(sn_mail_send($node)) { db_query('UPDATE {sn_subscriptions} SET s_status = %d WHERE snid = %d', 1, $mail->snid); $counter++; // don't send mails too fast, servers may choke. Wait for 10 ms. usleep(10000); } else { $message = t('Newsletter %title could not be sent to %email.', array('%title'=>theme('placeholder',$node->title), '%email'=>theme('placeholder',$mail->mail))); watchdog('newsletter', $message, WATCHDOG_ERROR); } if ($timer) { $int_time = sn_time(); } else { if ($counter < $throttle) { $int_time = $start_time; } else { return; } } if (!($int_time - $start_time < $max_time)) { return; } } db_query('UPDATE {sn_subscriptions} SET s_status = %d', 0); db_query('UPDATE {sn_newsletters} SET s_status = %d WHERE nid = %d', 2, $node->nid); if ($timer) { $int_time = sn_time(); } else { $int_time = $start_time; } if (!($int_time - $start_time < $max_time)) { return; } } } /** * Send a test newsletter */ function simplenews_send_test($input) { $tid = db_result(db_query('SELECT tid FROM {sn_newsletters} WHERE nid = %d', $input->nid)); $tid = $tid ? $tid : FALSE; $node = simplenews_node_prepare($input->nid, $tid); $term = $tid ? taxonomy_get_term($tid) : FALSE; $name = $term ? $term->name : 'Unassigned newsletter'; $node->title = "[$name] ".$node->title; $node->message = $node->body."\n\n--\n".t('Footer will be appended here'); $recipients = $input->test_address; foreach ($recipients as $to) { $node->to = $to; if (sn_mail_send($node)) { drupal_set_message(t('Test newsletter sent to %recipient', array('%recipient' => theme('placeholder', $to)))); } } } /** * Send confirmation email */ function sn_mail_confirm($email, $message, $newsletter, $snid = NULL, $tid = NULL, $op = NULL) { $mail->s_format = 'plain'; $mail->priority = 'none'; $address_default = variable_get('site_mail', ini_get('sendmail_from')); $name_default = variable_get('site_name', 'drupal'); $mail->from_address = variable_get('simplenews_from_address', $address_default); $mail->from_name = variable_get('simplenews_from_name', $name_default); $mail->to = $email; $mail->title = t('Confirmation for %newsletter from %site', array('%newsletter'=>$newsletter, '%site'=>variable_get('simplenews_from_name', $name_default))); $mail->message = t('This is a subscription status confirmation notice for the "%newsletter" newsletter.', array('%newsletter'=>$newsletter)); $mail->message .= "\n\n".$message; if ($snid && $tid) { $h = drupal_substr(md5($email . simplenews_private_key()), 0, 10).$snid.'t'.$tid; if ($op == 'subscribe') { $mail->message .= "\n\n--\n".t('Subscribe link:').' '.url('newsletter/confirm/add/'.$h, NULL, NULL, TRUE); } elseif ($op == 'unsubscribe') { $mail->message .= "\n\n--\n".t('Unsubscribe link:').' '.url('newsletter/confirm/remove/'.$h, NULL, NULL, TRUE); } } else { global $base_url; $mail->message .= "\n\n--\n".t('Visit our site:').' '.$base_url; } sn_mail_send($mail); } /** * Mail engine */ function sn_mail_send($mail) { $mail->to = trim($mail->to); require_once('activeMailLib.php'); $email = new activeMailLib($mail->s_format); $email->From($mail->from_address, $mail->from_name); $email->To($mail->to); $email->Subject($mail->title); $email->Message($mail->message, 'UTF-8', '8Bit'); $email->priority($mail->priority); if ($mail->receipt) { $email->Receipt($mail->from_address); } $email->Send(); return $email->isSent($mail->to); } /** * Other module-specific functions */ function sn_html_to_text($txt, $inline) { $pattern = '@(
]*>(.+?))@ei'; if ($inline) { $txt = preg_replace($pattern, "_sn_mail_uri('\\2', '\\3')", $txt); } else { $txt = preg_replace($pattern, "'\\3 ['. _sn_mail_urls('\\2') .']'", $txt); $urls = _sn_mail_urls(); if (count($urls)) { $txt .= "\n"; $i = 0; for ($max = count($urls); $i < $max; $i++) { $txt .= '['. ($i + 1) .'] '. $urls[$i] ."\n"; } } _sn_mail_urls(0, TRUE); } // some basic html to text conversion $txt = preg_replace(_sn_define_search(), _sn_define_replace(), $txt); $txt = preg_replace("/\n\s+\n/", "\n\n", $txt); $txt = strip_tags($txt); $txt = decode_entities($txt); return wordwrap($txt, 80); } function _sn_mail_uri($href, $link) { $href = _sn_mail_url($href); if ($href == $link) { $output = '['.$href.']'; } else { $output = $link.' ['.$href.']'; } return $output; } function _sn_mail_url($url) { if (preg_match('@://@', $url)) { return $url; } elseif (preg_match('!mailto:!i', $url)) { return str_replace('mailto:', '', $url); } else { return url($url, NULL, NULL, 1); } } function _sn_mail_urls($url = 0, $refresh = FALSE) { static $urls = array(); if($refresh) { $urls = array(); } if ($url) { $urls[] = _sn_mail_url($url); return count($urls); } return $urls; } /** * List of preg* regular expression patterns to search for, * used in conjunction with $replace. * Based on / modified from html2txt.module */ function _sn_define_search() { $search = array( "/\r/", // Non-legal carriage return "/[\t]+/", // tabs '/]*>.*?<\/script>/i', //