array( 'name' => t('Newsletter issue'), 'module' => 'simplenews', 'description' => t('A newsletter issue to be sent to subscribed email addresses.'), ) ); } /** * Implementation of hook_perm(). */ function simplenews_perm() { return array('view links in block', 'create newsletter', 'edit own newsletter', 'edit any newsletter', 'delete own newsletter', 'delete any newsletter', 'administer newsletters', 'administer simplenews settings', 'send newsletter', 'subscribe to newsletters'); } /** * Implementation of hook_access(). */ function simplenews_access($op, $node) { global $user; if ($op == 'create') { if (user_access('create newsletter')) { return TRUE; } } if ($op == 'update') { if (user_access('edit any newsletters')) { return TRUE; } elseif (user_access('edit own newsletter') && $user->uid == $node->uid) { return TRUE; } } if ($op == 'delete') { if (user_access('delete any newsletters')) { return TRUE; } elseif (user_access('delete own newsletter') && $user->uid == $node->uid) { return TRUE; } } } /** * Implementation of hook_init(). */ function simplenews_init() { drupal_add_css(drupal_get_path('module', 'simplenews') .'/simplenews.css', 'module', 'all', TRUE); // Simpelnews can not work without this variable. if ((variable_get('simplenews_vid', '')) == '') { drupal_set_message(t('Missing newsletter vocabulary. Please set a vocabulary at Simplenews settings.', array('@settings' => url('admin/settings/simplenews'))), 'error'); } } /** * Implementation of hook_menu(). */ function simplenews_menu() { $items['admin/content/simplenews'] = array( 'title' => 'Newsletters', 'description' => 'Manage newsletters and subscriptions.', 'type' => MENU_NORMAL_ITEM, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_news'), 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.admin.inc', ); $items['admin/content/simplenews/sent'] = array( 'title' => 'Sent issues', 'type' => MENU_DEFAULT_LOCAL_TASK, 'page arguments' => array('simplenews_admin_news'), 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.admin.inc', 'weight' => -10, ); $items['admin/content/simplenews/notsent'] = array( 'title' => 'Drafts', 'type' => MENU_LOCAL_TASK, 'page arguments' => array('simplenews_admin_news', 'notsent'), 'access arguments' => array('administer newsletters'), 'weight' => -9, ); $items['admin/content/simplenews/types'] = array( 'title' => 'Newsletters', 'type' => MENU_LOCAL_TASK, 'page callback' => 'simplenews_types_overview', 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.admin.inc', 'weight' => -8, ); $items['admin/content/simplenews/types/edit/%'] = array( 'title' => 'Newsletters', 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_types_form', 5), 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.admin.inc', ); $items['admin/content/simplenews/types/delete/%'] = array( 'title' => 'Newsletters', 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_types_delete', 5), 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.admin.inc', ); $items['admin/content/simplenews/types/list'] = array( 'title' => 'List newsletters', 'type' => MENU_DEFAULT_LOCAL_TASK, 'file' => 'simplenews.admin.inc', 'weight' => -10, ); $items['admin/content/simplenews/types/add'] = array( 'title' => 'Add newsletter', 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_types_form'), 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.admin.inc', 'weight' => -9, ); $items['admin/content/simplenews/subscriptions/delete'] = array( 'title' => 'Delete', 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_subscription_multiple_delete_confirm'), 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.admin.inc', ); $items['admin/content/simplenews/users'] = array( 'title' => 'Subscriptions', 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_subscription_admin'), 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.admin.inc', 'weight' => -7, ); $items['admin/content/simplenews/users/edit/%'] = array( 'title' => 'Subscriptions', 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_users_form', 5), 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.subscription.inc', ); $items['admin/content/simplenews/users/list'] = array( 'title' => 'List', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10, ); $items['admin/content/simplenews/users/import'] = array( 'title' => 'Mass subscribe', 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_subscription_list_add'), 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.admin.inc', 'weight' => -9, ); $items['admin/content/simplenews/users/unsubscribe'] = array( 'title' => 'Mass unsubscribe', 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_subscription_list_remove'), 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.admin.inc', 'weight' => -8, ); $items['admin/content/simplenews/users/export'] = array( 'title' => 'Export', 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_subscription_list_export'), 'access arguments' => array('administer newsletters'), 'file' => 'simplenews.admin.inc', 'weight' => -7, ); $items['admin/settings/simplenews'] = array( 'title' => 'Simplenews', 'description' => 'Manage simplenews configuration.', 'type' => MENU_NORMAL_ITEM, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_settings'), 'access arguments' => array('administer simplenews settings'), 'file' => 'simplenews.admin.inc', ); $items['admin/settings/simplenews/general'] = array( 'title' => 'General', 'type' => MENU_DEFAULT_LOCAL_TASK, 'page arguments' => array('simplenews_admin_settings'), 'access arguments' => array('administer simplenews settings'), 'file' => 'simplenews.admin.inc', 'weight' => -10, ); $items['admin/settings/simplenews/newsletter'] = array( 'title' => 'Newsletter', 'type' => MENU_LOCAL_TASK, 'page arguments' => array('simplenews_admin_settings_newsletter'), 'access arguments' => array('administer simplenews settings'), 'weight' => -9, ); $items['admin/settings/simplenews/subscription'] = array( 'title' => 'Subscription', 'type' => MENU_LOCAL_TASK, 'page arguments' => array('simplenews_admin_settings_subscription'), 'access arguments' => array('administer simplenews settings'), 'weight' => -8, ); $items['admin/settings/simplenews/mail'] = array( 'title' => 'Send mail', 'type' => MENU_LOCAL_TASK, 'page arguments' => array('simplenews_admin_settings_mail'), 'access arguments' => array('administer simplenews settings'), 'weight' => -7, ); $items['newsletter/confirm'] = array( 'title' => 'Confirm newsletter subscriptions', 'type' => MENU_CALLBACK, 'page callback' => 'simplenews_confirm_subscription', 'access arguments' => array('subscribe to newsletters'), 'file' => 'simplenews.subscription.inc', ); $items['newsletter/subscriptions'] = array( 'title' => 'Manage newsletter subscriptions', 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_subscription_manager_form'), 'access arguments' => array('subscribe to newsletters'), 'file' => 'simplenews.subscription.inc', ); return $items; } /** * Implementation of hook_nodeapi(). */ function simplenews_nodeapi(&$node, $op, $teaser, $page) { // Operate only on node types set in 'simplenews_content_types' variable. if (!in_array($node->type, variable_get('simplenews_content_types', array('simplenews')))) { return; } switch ($op) { case 'view': $node = simplenews_replace_vars($node, TRUE); break; case 'validate': global $_simplenews_valid_mails; if ($node->simplenews['send'] == SIMPLENEWS_COMMAND_SEND_NOW) { if (!isset($node->taxonomy)) { form_set_error('', t('You should assign content type %content_type to the !newsletter_vocabulary before you can send this newsletter.', array('%content_type' => $node->type, '!newsletter_vocabulary' => l(t('Newsletter vocabulary'), 'admin/content/taxonomy')))); } elseif (!simplenews_validate_taxonomy($node->taxonomy)) { form_set_error('taxonomy', t('You should select a newsletter term before you can send this newsletter issue.')); } } elseif ($node->simplenews['send'] == SIMPLENEWS_COMMAND_SEND_TEST) { $mails = explode(',', $node->simplenews['test_address']); foreach ($mails as $mail) { $mail = trim($mail); if ($mail == '') { form_set_error('simplenews][test_address', t('Cannot send test newsletter: no test email address specified.')); } elseif (!valid_email_address($mail)) { form_set_error('simplenews][test_address', t('Cannot send test newsletter to %mail: email address invalid.', array('%mail' => $mail))); } } } break; case 'presave': $term = simplenews_validate_taxonomy($node->taxonomy); $tid = is_array($term) ? array_values($term) : FALSE; $node->simplenews['tid'] = $tid ? $tid[0] : 0; break; case 'insert': case 'update': $send_with_permission = $node->simplenews['send'] == SIMPLENEWS_COMMAND_SEND_NOW && user_access('send newsletter'); if ($op == 'insert') { // Insert node $s_status = $send_with_permission ? SIMPLENEWS_STATUS_SEND_PENDING : SIMPLENEWS_STATUS_SEND_NOT; db_query("INSERT INTO {simplenews_newsletters} (nid, vid, tid, s_status, s_format, priority, receipt) VALUES (%d, %d, %d, %d, '%s', %d, %d)", $node->nid, $node->vid, $node->simplenews['tid'], $s_status, $node->simplenews['s_format'], $node->simplenews['priority'], $node->simplenews['receipt']); } else { // Update node if ($send_with_permission) { db_query("UPDATE {simplenews_newsletters} SET vid = %d, tid = %d, s_status = %d, s_format = '%s', priority = %d, receipt = %d WHERE nid = %d", $node->vid, $node->simplenews['tid'], SIMPLENEWS_STATUS_SEND_PENDING, $node->simplenews['s_format'], $node->simplenews['priority'], $node->simplenews['receipt'], $node->nid); } else { db_query("UPDATE {simplenews_newsletters} SET tid = %d, s_format = '%s', priority = %d, receipt = %d WHERE nid = %d", $node->simplenews['tid'], $node->simplenews['s_format'], $node->simplenews['priority'], $node->simplenews['receipt'], $node->nid); } } // When this node is selected for translation all translation of this node // will be send too. // All translated nodes will receive the same send states (priority, confirmation, format). if (module_exists('translation') && translation_supported_type($node->type) && $send_with_permission) { if ($translations = translation_node_get_translations($node->tnid)) { foreach ($translations as $translation) { db_query("UPDATE {simplenews_newsletters} SET s_status = %d, s_format = '%s', priority = %d, receipt = %d WHERE nid = %d", SIMPLENEWS_STATUS_SEND_PENDING, $node->simplenews['s_format'], $node->simplenews['priority'], $node->simplenews['receipt'], $translation->nid); } } } // Send newsletter or test newsletter if ($send_with_permission) { // Send newsletter to all subscribers simplenews_send_node($node); } elseif ($node->simplenews['send'] == SIMPLENEWS_COMMAND_SEND_TEST) { // Send test newsletter to test address(es) simplenews_send_test($node); } break; case 'delete': $result = db_query('DELETE FROM {simplenews_newsletters} WHERE nid = %d', $node->nid); if ($result) { drupal_set_message(t('Newsletter %title was deleted.', array('%title' => $node->title))); } break; case 'load': $node->simplenews = db_fetch_array(db_query('SELECT * FROM {simplenews_newsletters} WHERE nid = %d', $node->nid)); break; } } /** * Implementation of hook_form(). */ function simplenews_form(&$node) { $type = node_get_types('type', $node); if ($type->has_title) { $form['title'] = array( '#type' => 'textfield', '#title' => check_plain($type->title_label), '#required' => TRUE, '#default_value' => $node->title, '#maxlength' => 255, '#weight' => -5, ); } if ($type->has_body) { $form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count); // Available variables are based on user_mail_tokens(). // But uses only those which can be used with uid = 0 since simplenews also sends to anonymous users. $form['body_field']['body']['#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://),') .' !date '. t("(today's date),") .' !login_uri '. t('(link to login page).'); } return $form; } /** * Validate if selected terms are Newsletter taxonomy terms. * * @param array $taxonomy Taxonomy form array of newsletter node. * * @return * Array of selected Newsletter terms. Example: array(4, 12) * FALSE: no Newsletter term is selected * * NOTE: This function can not handle free tagging tags. * In case of free tagging see taxonomy_node_save() for example code. * Note that free tagging can create new terms at node add/edit. This * contradicts with the current set-up of simpelnews. */ function simplenews_validate_taxonomy($taxonomy) { // Get newsletter tids. $vid = variable_get('simplenews_vid', ''); $result = db_query('SELECT tid FROM {term_data} WHERE vid = %d', $vid); while ($tid = db_fetch_object($result)) { $newsletter_tids[] = $tid->tid; } // Extract selected tid's from the taxonomy form. if (isset($newsletter_tids) && !empty($taxonomy)) { $selected_terms = array(); if (is_array($taxonomy)) { foreach ($taxonomy as $term) { if (is_array($term)) { foreach ($term as $tid) { if ($tid) { $selected_terms[] = $tid; } } } else if (is_object($term)) { $selected_terms[] = $term->tid; } else if ($term) { $selected_terms[] = $term; } } } // Compare selected tid's and newsletter tid's. $valid_terms = array_intersect($newsletter_tids, $selected_terms); return empty($valid_terms) ? FALSE : $valid_terms; } return FALSE; } /** * Implementation of hook_form_alter(). */ function simplenews_form_alter(&$form, $form_state, $form_id) { $vid = variable_get('simplenews_vid', ''); // Newsletter vocabulary form if ($form_id == 'taxonomy_form_vocabulary' && isset($form['vid']) && $form['vid']['#value'] == $vid) { // Hide critical options from newsletter vocabulary. $form['help_simplenews_vocab'] = array( '#value' => t('This is the designated simplenews vocabulary.'), '#weight' => -1, ); $form['content_types']['nodes']['#description'] = t('These content type(s) are used as newsletter. They can also be set in !simplenews_settings.', array('!simplenews_settings' => l('Simplenews settings', 'admin/settings/simplenews'))); // Free tagging can not be allowed see: simplenews_validate_taxonomy(). $form['settings']['tags'] = array('#type' => 'value', '#value' => FALSE); } // Simplenews newsletter node form elseif (strpos($form_id, '_node_form')) { if (in_array($form['type']['#value'], variable_get('simplenews_content_types', array('simplenews')))) { if (isset($form['#node']->simplenews)) { $simplenews_values = $form['#node']->simplenews; } $vocabulary = taxonomy_vocabulary_load(variable_get('simplenews_vid', '')); if (!empty($vocabulary) && !isset($vocabulary->nodes[$form['type']['#value']])) { drupal_set_message(t('Invalid node type or vocabulary setting. Please check the Simplenews general settings.', array('%name' => $vocabulary->name, '@settings' => url('admin/settings/simplenews'))), 'error'); } $form['simplenews'] = array( '#type' => 'fieldset', '#title' => t('Newsletter sending options'), '#collapsible' => TRUE, '#collapsed' => FALSE, '#tree' => TRUE, ); // Show newsletter sending options if newsletter has not been send yet. // If send a nodification is shown. if (!isset($simplenews_values['s_status']) || (isset($simplenews_values['s_status']) && $simplenews_values['s_status'] == SIMPLENEWS_STATUS_SEND_NOT)) { // Hide format selection if there is nothing to choose. // The default format is plain text. $format_options = _simplenews_format_options(); if (count($format_options) > 1) { $form['simplenews']['s_format'] = array( '#type' => 'select', '#title' => t('Format'), '#default_value' => isset($simplenews_values['s_format']) ? $simplenews_values['s_format'] : variable_get('simplenews_format', 'plain'), '#options' => _simplenews_format_options(), ); } else { $form['simplenews']['s_format'] = array( '#type' => 'hidden', '#value' => key($format_options), ); } $form['simplenews']['priority'] = array( '#type' => 'select', '#title' => t('Priority'), '#default_value' => isset($simplenews_values['priority']) ? $simplenews_values['priority'] : variable_get('simplenews_priority', SIMPLENEWS_PRIORITY_NONE), '#options' => array( SIMPLENEWS_PRIORITY_NONE => t('none'), SIMPLENEWS_PRIORITY_HIGHEST => t('highest'), SIMPLENEWS_PRIORITY_HIGH => t('high'), SIMPLENEWS_PRIORITY_NORMAL => t('normal'), SIMPLENEWS_PRIORITY_LOW => t('low'), SIMPLENEWS_PRIORITY_LOWEST => t('lowest'), ), ); $form['simplenews']['receipt'] = array( '#type' => 'checkbox', '#title' => t('Request receipt'), '#return_value' => 1, '#default_value' => isset($simplenews_values['receipt']) ? $simplenews_values['receipt'] : variable_get('simplenews_receipt', 0), ); if (user_access('send newsletter')) { $options[SIMPLENEWS_COMMAND_SEND_NONE] = t("Don't send now"); $options[SIMPLENEWS_COMMAND_SEND_TEST] = t('Send one test newsletter to the test address'); $options[SIMPLENEWS_COMMAND_SEND_NOW] = t('Send newsletter'); $form['simplenews']['send'] = array( '#type' => 'radios', '#title' => t('Sending'), '#default_value' => isset($simplenews_values['send']) ? $simplenews_values['send'] : variable_get('simplenews_send', SIMPLENEWS_COMMAND_SEND_NONE), '#options' => $options, ); } else { $options[SIMPLENEWS_COMMAND_SEND_NONE] = t("Don't send now"); $options[SIMPLENEWS_COMMAND_SEND_TEST] = t('Send one test newsletter to the test address'); $form['simplenews']['send'] = array( '#type' => 'radios', '#title' => t('Sending'), '#default_value' => isset($simplenews_values['send']) ? $simplenews_values['send'] : SIMPLENEWS_COMMAND_SEND_NONE, '#options' => $options, '#description' => t('You have no privileges to send this newsletter'), ); } if (module_exists('translation') && translation_supported_type($form['#node']->type)) { $form['simplenews']['send']['#description'] = t('This newsletter issue is part of a translation set. All translations in this set will be send when you send this node.'); } $address_default = variable_get('site_mail', ini_get('sendmail_from')); if (variable_get('simplenews_test_address_override', 0)) { $form['simplenews']['test_address'] = array( '#type' => 'textfield', '#title' => t('Test email addresses'), '#description' => t('Supply a comma-separated list of email addresses to be used as test addresses.'), '#default_value' => isset($simplenews_values['test_address']) ? $simplenews_values['test_address'] : variable_get('simplenews_test_address', $address_default), '#size' => 60, '#maxlength' => 128, ); } else { $form['simplenews']['test_address'] = array( '#type' => 'hidden', '#value' => variable_get('simplenews_test_address', $address_default), ); } } else { $form['simplenews']['none'] = array( '#type' => 'checkbox', '#title' => t('This newsletter has been sent'), '#return_value' => 0, '#attributes' => array('checked' => 'checked', 'disabled' => 'disabled'), ); } $form['simplenews']['s_status'] = array( '#type' => 'hidden', '#value' => isset($simplenews_values['s_status']) ? $simplenews_values['s_status'] : SIMPLENEWS_STATUS_SEND_NOT, ); } } } /** * Implementation of hook_cron(). */ function simplenews_cron() { simplenews_mail_send(); simplenews_clear_spool(); } /** * Implementation of hook_taxonomy(). * * Deletes subscriptions to term when term is deleted, and cleans the blocks * table. */ function simplenews_taxonomy($op, $type, $term = NULL) { if ($op == 'delete' && $term['vid'] == variable_get('simplenews_vid', '')) { switch ($term) { case 'term': db_query('DELETE FROM {simplenews_snid_tid} WHERE tid = %d', $array['tid']); db_query("DELETE FROM {blocks} WHERE module = '%s' AND delta = '%s'", 'simplenews', $term['tid']); drupal_set_message(t('All subscriptions to newsletter %newsletter have been deleted.', array('%newsletter' => $term['name']))); break; } } } /** * 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 * simplenews_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 {simplenews_subscriptions} WHERE mail = '%s'"; if ($result = db_fetch_object(db_query($query, $edit['mail']))) { db_query("UPDATE {simplenews_subscriptions} SET uid = %d, language = '%s' WHERE snid = %d", $edit['uid'], $edit['language'], $result->snid); } } break; case 'update': if ($category == 'account' && $edit['mail']) { $query = "SELECT snid FROM {simplenews_subscriptions} WHERE uid = %d"; if ($result = db_fetch_object(db_query($query, $account->uid))) { db_query("DELETE FROM {simplenews_subscriptions} WHERE mail = '%s' AND uid = %d", $edit['mail'], 0); db_query("UPDATE {simplenews_subscriptions} SET mail = '%s', language = '%s' WHERE snid = %d", $edit['mail'], $edit['language'], $result->snid); } else { $query = "SELECT snid FROM {simplenews_subscriptions} WHERE mail = '%s'"; if ($result = db_fetch_object(db_query($query, $edit['mail']))) { db_query("UPDATE {simplenews_subscriptions} SET uid = %d, language = '%s' WHERE snid = %d", $account->uid, $account->language, $result->snid); } } } // Activate/deactivate subscription when account is blocked/unblocked if ($category == 'account' && isset($edit['status'])) { if (variable_get('simplenews_sync_account', TRUE)) { db_query("UPDATE {simplenews_subscriptions} SET activated = %d WHERE uid = %d", $edit['status'], $account->uid); } } if ($category == 'newsletter' && user_access('subscribe to newsletters')) { foreach ($edit['newsletters'] as $tid => $checked) { if ($checked) { simplenews_subscribe_user($account->mail, $tid, FALSE); } else { simplenews_unsubscribe_user($account->mail, $tid, FALSE); } } } break; case 'delete': if (variable_get('simplenews_sync_account', TRUE)) { // Delete subscription and all newsletter subscriptions when account is removed. // We don't use simplenews_get_subscription() here because the user is already // deleted from the {user} table. $snid = db_result(db_query("SELECT s.snid FROM {simplenews_subscriptions} s WHERE s.mail = '%s'", $account->mail)); db_query('DELETE FROM {simplenews_snid_tid} WHERE snid = %d', $snid); db_query('DELETE FROM {simplenews_subscriptions} WHERE snid = %d', $snid); } else { // Only remove uid from subscription data when account is removed db_query("UPDATE {simplenews_subscriptions} SET uid = 0 WHERE uid = %d", $account->uid); } break; case 'form': if ($category == 'newsletter' && user_access('subscribe to newsletters')) { $subscription = simplenews_get_subscription($account); $form = _simplenews_subscription_manager_form($subscription); $form['subscriptions']['#title'] = t('Current newsletter subscriptions'); unset($form['update'], $form['subscriptions']['mail']); return $form; } break; case 'categories': if (user_access('subscribe to newsletters')) { $output[] = array('name' => 'newsletter', 'title' => t('My newsletters'), 'weight' => 10); } return $output; case 'view': global $user; if ($user->uid == $account->uid || user_access('administer users')) { $account->content['simplenews'] = array( '#type' => 'user_profile_category', '#title' => t('Newsletters'), ); $tree = taxonomy_get_tree(variable_get('simplenews_vid', '')); foreach ($tree as $newsletter) { if (db_result(db_query('SELECT COUNT(s.uid) FROM {simplenews_subscriptions} s INNER JOIN {simplenews_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 (isset($subscriptions)) { $subscriptions = implode(', ', $subscriptions); } else { $subscriptions = t('None'); } // When a user has no permission to subscribe and is not subscribed // we do not display the 'no subscriptions' message. if (user_access('subscribe to newsletters') || $subscriptions != t('None')) { $account->content['simplenews']['subscriptions'] = array( '#type' => 'user_profile_item', '#title' => t('Current subscriptions'), '#value' => $subscriptions, ); } if (user_access('subscribe to newsletters')) { $account->content['simplenews']['my_newsletters'] = array( '#type' => 'user_profile_item', '#value' => t('Manage !my_subscriptions', array('!my_subscriptions' => l(t('my subscriptions'), 'user/'. $account->uid .'/edit/newsletter'))), '#weight' => -1, ); } return array(t('Newsletters') => $items); } break; } } /** * Implementation of hook_block(). */ function simplenews_block($op = 'list', $delta = 0, $edit = array()) { switch ($op) { case 'list': $blocks = array(); foreach (taxonomy_get_tree(variable_get('simplenews_vid', '')) as $newsletter) { //TODO: 1. without form -> by role; 2. with form -> user caching with refresh on subscribe/unsubscribe (option as setting) or no caching $blocks[$newsletter->tid] = array( 'info' => t('Newsletter: @title', array('@title' => $newsletter->name)), 'cache' => variable_get('simplenews_block_f_'. $newsletter->tid, 1) ? BLOCK_NO_CACHE : BLOCK_CACHE_PER_ROLE, ); } return $blocks; case 'configure': $form['simplenews_block_'. $delta]['simplenews_block_m_'. $delta] = array( '#type' => 'textfield', '#title' => t('Block message'), '#size' => 60, '#maxlength' => 128, '#default_value' => variable_get('simplenews_block_m_'. $delta, t('Stay informed on our latest news!')), ); $form['simplenews_block_'. $delta]['simplenews_block_f_'. $delta] = array( '#type' => 'radios', '#title' => t('Subscription interface'), '#options' => array('1' => t('Subscription form'), '0' => t('Link to form')), '#description' => t("Note: this requires permission 'subscribe to newsletters'."), '#default_value' => variable_get('simplenews_block_f_'. $delta, 1), ); $form['simplenews_block_'. $delta]['simplenews_block_l_'. $delta] = array( '#type' => 'checkbox', '#title' => t('Display link to previous issues'), '#return_value' => 1, '#default_value' => variable_get('simplenews_block_l_'. $delta, 1), '#description' => t("Note: this requires permission 'view links in block'."), ); $form['simplenews_block_'. $delta]['simplenews_block_i_status_'. $delta] = array( '#type' => 'checkbox', '#title' => t('Display previous issues'), '#return_value' => 1, '#default_value' => variable_get('simplenews_block_i_status_'. $delta, 0), '#description' => t("Note: this requires permission 'view links in block'."), ); $form['simplenews_block_'. $delta]['simplenews_block_i_'. $delta] = array( '#type' => 'select', '#title' => t('Number of issues to display'), '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), '#default_value' => variable_get('simplenews_block_i_'. $delta, 5), ); $form['simplenews_block_'. $delta]['simplenews_block_r_'. $delta] = array( '#type' => 'checkbox', '#title' => t('Display RSS-feed icon'), '#return_value' => 1, '#default_value' => variable_get('simplenews_block_r_'. $delta, 1), '#description' => t("Note: this requires permission 'view links in block'."), ); return $form; case 'save': variable_set('simplenews_block_m_'. $delta, $edit['simplenews_block_m_'. $delta]); variable_set('simplenews_block_f_'. $delta, $edit['simplenews_block_f_'. $delta]); variable_set('simplenews_block_l_'. $delta, $edit['simplenews_block_l_'. $delta]); variable_set('simplenews_block_i_status_'. $delta, $edit['simplenews_block_i_status_'. $delta]); variable_set('simplenews_block_i_'. $delta, $edit['simplenews_block_i_'. $delta]); variable_set('simplenews_block_r_'. $delta, $edit['simplenews_block_r_'. $delta]); break; case 'view': global $language; if ($tree = taxonomy_get_tree(variable_get('simplenews_vid', ''))) { // Only display a block if $delta is a valid newsletter term id. foreach ($tree as $taxonomy) { $tids[] = $taxonomy->tid; } if (in_array($delta, $tids)) { // $delta is validated, the block can be displayed. $newsletter = (array) taxonomy_get_term($delta); // Translate newsletter name if required. if (module_exists('i18ntaxonomy') && i18ntaxonomy_vocabulary(variable_get('simplenews_vid', '')) == I18N_TAXONOMY_LOCALIZE) { $newsletter['name'] = tt('taxonomy:term:'. $newsletter['tid'] .':name', $newsletter['name'], $language->language); } $block = array( 'subject' => check_plain($newsletter['name']), 'content' => theme('simplenews_block', $newsletter['tid']), ); return $block; } else { drupal_set_message(t('You have probably changed the newsletter vocabulary. Please redefine the newsletter blocks.', array('@blocks' => url('admin/build/block'))), 'error'); return array(); } } break; } } /** * Implementation of hook_forms(). * * All form blocks are build using simplenews_block_form(). * hook_forms() is required to provide unique form id for each block form. */ function simplenews_forms() { if ($taxonomies = taxonomy_get_tree(variable_get('simplenews_vid', ''))) { foreach ($taxonomies as $newsletter) { $forms['simplenews_block_form_'. $newsletter->tid] = array( 'callback' => 'simplenews_block_form', 'callback arguments' => array($newsletter->tid), ); } } return $forms; } /** * Load a user or creates a dummy anonymous user. * * @return account * object ( * mail, email address * uid, uid or 0 for anonymous * ) */ function _simplenews_user_load($mail) { $account = user_load(array('mail' => $mail)); if ($account === FALSE) { // Construct anonymous user since we don't have a user that matches that e-amil. $account = new stdClass(); $account->uid = 0; $account->mail = drupal_strtolower($mail); } return $account; } /** * Subscribe a user to a newsletter or send a confirmation mail. * * The $confirm parameter determines the action: * FALSE = The user is subscribed * TRUE = User receives an email to verify the address and complete the subscription * A new subscription account is created when the user is subscribed to the first newsletter * * @param string $mail * The email address to subscribe to the newsletter. * @param integer $tid * The term ID of the newsletter. * @param boolean $confirm * TRUE = send confirmation mail; FALSE = subscribe immediate to the newsletter * @param string $preferred_language * The language code (i.e. 'en', 'nl') of the user preferred language. * Use '' for the site default language. * Use NULL for the language of the current page. */ function simplenews_subscribe_user($mail, $tid, $confirm = TRUE, $preferred_language = NULL) { global $language; //Prevent mismatches from accidental capitals in mail address $mail = strtolower($mail); // Get current subscriptions if any. $account = (object) array('mail' => $mail); $subscription = simplenews_get_subscription($account); // If user is not subscribed to ANY newsletter, create a subscription account if ($subscription->snid == 0) { // To subscribe a user: // - Fetch the users uid. // - Determine the user preferred language. // - Add the user to the database. // - Get the full subscription object based on the mail address. // Note that step 3 gets subscription data based on mail address because the uid can be 0 (for anonymous users) $account = _simplenews_user_load($mail); // If the site is multilingual: // - Anonymous users are subscribed with their preferred language // equal to the language of the current page. // - Registered users will be subscribed with their default language as // set in their account settings. // By default the preferred language is not set. if (variable_get('language_count', 1) > 1) { if ($account->uid) { $preferred_language = $account->language; } else { $preferred_language = isset($preferred_language) ? $preferred_language : $language->language; } } db_query("INSERT INTO {simplenews_subscriptions} (mail, uid, language, activated) VALUES ('%s', %d, '%s', %d)", $mail, $account->uid, $preferred_language, 1); $subscription = simplenews_get_subscription($account); } if ($confirm) { // Send confirmation email to user to complete subscription or to tell // them that he or she is already subscribed. // Confirmation mail is in the user preferred language which is by default the language_default(). $params['from'] = _simplenews_set_from(); $params['newsletter'] = taxonomy_get_term($tid); $params['context']['account'] = $subscription; drupal_mail('simplenews', 'subscribe', $mail, $subscription->language, $params, $params['from']['address']); } elseif (!isset($subscription->tids[$tid])) { // OR add user to newsletter relationship if not already subscribed. db_query("INSERT INTO {simplenews_snid_tid} (snid, tid) VALUES (%d, %d)", $subscription->snid, $tid); // Execute simplenews subscribe trigger. simplenews_call_actions('subscribe', $subscription); } return TRUE; } /** * Unsubscribe a user from a newsletter or send a confirmation mail. * * The $confirm parameter determines the action: * FALSE = The user is unsubscribed * TRUE = User receives an email to verify the address and complete the unsubscription * The subscription account is deleted when the user is unsubscribed to the last newsletter * * @param string $mail The email address to unsubscribe from the newsletter. * @param integer $tid The term ID of the newsletter. * @param boolean $confirm TRUE = send confirmation mail; FALSE = unsubscribe immediate from the newsletter */ function simplenews_unsubscribe_user($mail, $tid, $confirm = TRUE) { //Prevent mismatches from accidental capitals in mail address $mail = strtolower($mail); $account = (object) array('mail' => $mail); $subscription = simplenews_get_subscription($account); // The unlikely case that a user is subscribed from a non existing newsletter is logged if (!$newsletter = taxonomy_get_term($tid)) { watchdog('simplenews', 'Attempt to unsubscribe from non existing newsletter term ID %id', array('%id' => $tid), WATCHDOG_ERROR); return FALSE; } if ($confirm) { // Send confirmation email to user to complete unsubscription // or to tell them that he or she is not subscribed // Confirmation mail is in the user preferred language. $params['from'] = _simplenews_set_from(); $params['newsletter'] = $newsletter; $params['context']['account'] = $subscription; drupal_mail('simplenews', 'unsubscribe', $mail, $subscription->language, $params, $params['from']['address']); } elseif (isset($subscription->tids[$tid])) { // OR remove the user from the newsletter. db_query('DELETE FROM {simplenews_snid_tid} WHERE snid = %d AND tid = %d', $subscription->snid, $tid); // Clean up subscription account if user is not subscribed to any newsletter anymore if (!db_result(db_query("SELECT COUNT(*) FROM {simplenews_snid_tid} t WHERE t.snid = %d", $subscription->snid))) { db_query('DELETE FROM {simplenews_subscriptions} WHERE snid = %d', $subscription->snid); } // Execute simplenews unsubscribe trigger simplenews_call_actions('unsubscribe', $subscription); } return TRUE; } /** * Check if the email address is subscribed to the given newsletter. * * @param string $mail email address * @param integer $tid newsletter term id * * @return boolean TRUE = email address is subscribed to given newsletter term id */ function simplenews_user_is_subscribed($mail, $tid, $reset = FALSE) { static $subscribed = array(); if ($reset) { unset($subscribed); } if (!isset($subscribed[$mail][$tid])) { $subscribed[$mail][$tid] = db_result(db_query("SELECT COUNT(*) FROM {simplenews_subscriptions} s INNER JOIN {simplenews_snid_tid} t ON s.snid = t.snid WHERE s.mail = '%s' AND t.tid = %d", $mail, $tid)) ? TRUE : FALSE; } return $subscribed[$mail][$tid]; } /** * Get the subscription object for the given account. * * Account is defined by (in order of preference) snid, email address or uid. * If the account is not subscribed a default subscription object is returned * containing all available account info. * * @param object $account account details. Containing one or none of these items: * object( * snid : subscription id * mail : email address * uid : user id * ) * * @return subscription object * object( * snid : subscription id. 0 if account is not subscribed * tids : array of newsletter tid's * uid : user id. 0 if account is anonymous user * mail : user email address. empty if email is unknown * name : always empty. Added for compatebility with user account object * language : language object. User preferred or default language * ) */ function simplenews_get_subscription($account) { // Load subscription data based on available account informatioin // NOTE that the order of checking for snid, mail and uid is critical. mail must be checked *before* uid. See simplenews_subscribe_user() if (isset($account->snid)) { $subscription = db_fetch_object(db_query("SELECT s.* FROM {simplenews_subscriptions} s INNER JOIN {users} u ON u.uid = s.uid WHERE s.snid = %d", $account->snid)); } elseif (isset($account->mail)) { $subscription = db_fetch_object(db_query("SELECT s.* FROM {simplenews_subscriptions} s INNER JOIN {users} u ON u.uid = s.uid WHERE s.mail = '%s'", $account->mail)); } elseif (isset($account->uid) && $account->uid > 0) { $subscription = db_fetch_object(db_query("SELECT s.* FROM {simplenews_subscriptions} s INNER JOIN {users} u ON u.uid = s.uid WHERE s.uid = %d", $account->uid)); } if ($subscription) { $result = db_query("SELECT tid FROM {simplenews_snid_tid} t WHERE t.snid = %d", $subscription->snid); $subscription->tids = array(); while ($newsletter = db_fetch_object($result)) { $subscription->tids[$newsletter->tid] = $newsletter->tid; } $subscription->name = ''; $subscription->language = user_preferred_language($subscription, language_default()); } else { // Account is unknown in subscription table. Create default subscription object $subscription = new stdClass(); $subscription->name = ''; $subscription->uid = isset($account->uid) ? $account->uid : 0; $subscription->mail = isset($account->mail) ? $account->mail : ''; $subscription->language = language_default(); $subscription->snid = 0; $subscription->tids = array(); } return $subscription; } /** * Delete every subscription for the given subscription ID. * * @param integer $snid subscription id */ function simplenews_delete_subscription($snid) { $account = db_fetch_object(db_query('SELECT mail FROM {simplenews_subscriptions} WHERE snid = %d', $snid)); db_query('DELETE FROM {simplenews_subscriptions} WHERE snid = %d', $snid); db_query('DELETE FROM {simplenews_snid_tid} WHERE snid = %d', $snid); watchdog('simplenews', 'User %email deleted from the mailing list.', array('%email' => $account->mail), WATCHDOG_NOTICE); } /** * Build subscription manager form. * * @param object $subscription subscription object */ function _simplenews_subscription_manager_form($subscription) { $form = array(); $options = array(); foreach (taxonomy_get_tree(variable_get('simplenews_vid', '')) as $newsletter) { $options[$newsletter->tid] = check_plain($newsletter->name); $default_value[$newsletter->tid] = FALSE; } $form['subscriptions'] = array( '#type' => 'fieldset', '#description' => t('Select the newsletter(s) to which you want to subscribe or unsubscribe.'), ); $form['subscriptions']['newsletters'] = array( '#type' => 'checkboxes', '#options' => $options, '#default_value' => array_merge($default_value, (array)$subscription->tids), ); // If current user is logged in, just display email. // Anonymous users see an email box and will receive confirmations if ($subscription->mail) { $form['subscriptions']['#title'] = t('Subscriptions for %mail', array('%mail' => $subscription->mail)); $form['subscriptions']['mail'] = array('#type' => 'value', '#value' => $subscription->mail); $form['update'] = array( '#type' => 'submit', '#value' => t('Update'), '#weight' => 20, ); } else { $form['subscriptions']['#title'] = t('Manage your newsletter subscriptions'); $form['subscriptions']['mail'] = array( '#type' => 'textfield', '#title' => t('email'), '#size' => 20, '#maxlength' => 128, '#weight' => 10, '#required' => TRUE, ); $form['subscribe'] = array( '#type' => 'submit', '#value' => t('Subscribe'), '#weight' => 20, ); $form['unsubscribe'] = array( '#type' => 'submit', '#value' => t('Unsubscribe'), '#weight' => 30, ); } return $form; } /** * Create a list of recent newsletters. * * @param integer $tid term id of selected newsletter * @param integer $count number of newsletters in the list */ function simplenews_recent_newsletters($tid, $count = 5) { $result = db_query_range(db_rewrite_sql('SELECT n.nid, n.title, sn.s_status FROM {node} n INNER JOIN {term_node} t ON n.vid = t.vid INNER JOIN {simplenews_newsletters} sn ON n.nid = sn.nid WHERE (t.tid = %d AND n.status = %d) ORDER BY n.created DESC'), $tid, 1, 0, $count); $titles = array(); while ($item = db_fetch_object($result)) { $titles[$item->nid]['data'] = l($item->title, 'node/'. $item->nid); $titles[$item->nid]['class'] = ($item->s_status == SIMPLENEWS_STATUS_SEND_NOT) ? 'newsletter-created' : 'newsletter-send'; } return $titles; } /** * Newsletter (un)subscription form for authenticated and anonymous users. * * @param $tid term id of selected newsletter. * * @see simplenews_block_form_validate() * @see simplenews_block_form_submit() */ function simplenews_block_form(&$form_state, $tid) { global $user; $form = array(); if ($user->uid) { if (simplenews_user_is_subscribed($user->mail, $tid)) { $submit_text = t('Unsubscribe'); $form['action'] = array('#type' => 'value', '#value' => 'unsubscribe'); } else { $submit_text = t('Subscribe'); $form['action'] = array('#type' => 'value', '#value' => 'subscribe'); } $form['display_mail'] = array( '#type' => 'item', '#title' => t('User'), '#value' => check_plain($user->name), ); $form['mail'] = array('#type' => 'value', '#value' => $user->mail); } else { $form['mail'] = array( '#type' => 'textfield', '#title' => t('Email'), '#size' => 20, '#maxlength' => 128, '#required' => TRUE, ); $form['action'] = array( '#type' => 'radios', '#default_value' => 'subscribe', '#options' => array('subscribe' => t('Subscribe'), 'unsubscribe' => t('Unsubscribe')), ); } // All block forms use the same validate and submit function. // #tid carries the tid for processing of the right newsletter issue term. $form['#tid'] = $tid; $form['#validate'][] = 'simplenews_block_form_validate'; $form['#submit'][] = 'simplenews_block_form_submit'; $form['submit'] = array( '#type' => 'submit', '#value' => isset($submit_text) ? $submit_text : t('Save') ); return $form; } function simplenews_block_form_validate($form, &$form_state) { if (!valid_email_address($form_state['values']['mail'])) { form_set_error('mail', t("The email address you supplied is not valid.")); } } function simplenews_block_form_submit($form, &$form_state) { global $user; $tid = $form['#tid']; $account = _simplenews_user_load($form_state['values']['mail']); // If email belongs to the current registered user, don't send confirmation. $confirm = $account->uid && $account->uid == $user->uid ? FALSE : TRUE; switch ($form_state['values']['action']) { case 'subscribe': simplenews_subscribe_user($form_state['values']['mail'], $tid, $confirm); if ($confirm) { drupal_set_message(t('You will receive a confirmation email shortly containing further instructions on how to complete your subscription.')); } else { drupal_set_message(t('You have been subscribed.')); } break; case 'unsubscribe': simplenews_unsubscribe_user($form_state['values']['mail'], $tid, $confirm); if ($confirm) { drupal_set_message(t('You will receive a confirmation email shortly containing further instructions on how to complete the unsubscription process.')); } else { drupal_set_message(t('You have been unsubscribed.')); } break; } } /** * Send newsletter node to subcribers. * * @param integer or object $node Newsletter node to be send. integer = nid; object = node object * @param array $accounts account objects to send the newsletter to. * account = object ( * snid = subscription id. 0 if no subscription record exists * tids = array(tid) array of newsletter tid's * uid = user id. 0 if subscriber is anonymous user. * mail = user email address. * name = . Added for compatebility with user account object * language = language object. User preferred of default language * ) * NOTE: either snid, mail or uid is required. */ function simplenews_send_node($node, $accounts = array()) { $mails = array(); if (is_numeric($node)) { $node = node_load($node); } if (is_object($node)) { $from = _simplenews_set_from($node); $params['context']['node'] = $node; $params['from'] = $from; $node_data['tid'] = $node->simplenews['tid']; $node_data['nid'] = $node->nid; $node_data['vid'] = $node->vid; if (empty($accounts)) { // No accounts specified. Get email address of all accounts subscribed to this newsletter. $result = db_query('SELECT s.mail FROM {simplenews_subscriptions} s INNER JOIN {simplenews_snid_tid} t ON s.snid = t.snid WHERE s.activated = %d AND t.tid = %d', 1, $node_data['tid']); while ($account = db_fetch_object($result)) { $mails[] = array('mail' => $account->mail); } } else { // Get email address of specified accounts. foreach ($accounts as $account) { $account = simplenews_get_subscription($account); $mails[] = array('mail' => $account->mail); } } // When cron is not used (simplenews_use_cron = FALSE) the spool content // is send immediately after filling the spool. When cron is used spooled // emails are send on each cron run. foreach ($mails as $mail) { $data = array_merge($node_data, $mail); simplenews_mail_spool_set($data); } if (variable_get('simplenews_use_cron', TRUE) == FALSE) { simplenews_mail_send($node_data['nid'], $node_data['vid'], 999999); drupal_set_message(t('Newsletter sent.')); simplenews_clear_spool(); } else { drupal_set_message(t('Newsletter pending.')); } } } /** * Send test version of newsletter. * * @param integer or object $node Newsletter node to be send. Integer = nid; Object = node object * @param array $accounts account objects to send the test newsletter to. * account = object( * mail : email address of recipient * ) */ function simplenews_send_test($node, $accounts = array()) { if (is_numeric($node)) { $node = node_load($node); } if (is_object($node)) { $from = _simplenews_set_from($node); $params['context']['node'] = $node; $params['from'] = $from; // If no account is specified the test newsletter is send to the test address(es) specified in the node. if (empty($accounts)) { // Build array of test email addresses $mails = explode(',', $node->simplenews['test_address']); foreach ($mails as $mail) { $account['mail'] = trim($mail); $accounts[] = (object)$account; } } // Test emails are send directly by drupal_mail(). This in contrast to simplenews_send_node() which send via a buffer. foreach ($accounts as $account) { $subscription = simplenews_get_subscription($account); $params['context']['account'] = $subscription; $result = drupal_mail('simplenews', 'test', $account->mail, $subscription->language, $params, $from['address']); if ($result['result']) { drupal_set_message(t('Test newsletter sent to %recipient.', array('%recipient' => $account->mail))); } } } } /** * Implementation of hook_mail(). * * Send simplenews mails using drupal mail API * @see drupal_mail() * * @param $key: node | test | subscribe | unsubscribe * @param array $message message array * [from] * [headers][From] * [language] : preferred message language * @param array $params parameter array * [context][node] : node object of message to be send * [context][snid] : used for $key = subscribe or unsubscribe * [context][from_name] : name of mail sender or site name (optional) * [context][account] : account details of recipient * [from] : array('address' => 'noreply@example.org', 'formatted' => 'site name ') * [newsletter] : newsletter object (tid, name) * [tokens] : tokens for variable replacement. Defaults to: user_mail_tokens() */ function simplenews_mail($key, &$message, $params) { $context = $params['context']; switch ($key) { case 'node': case 'test': // Message header, body and mail headers are buffered to increase // perfomance when sending multiple mails. Buffered data only contains // general data, no recipient specific content. Placeholders are used // for recipient data and will later be replaced. // When mailing multiple newsletters in one page call or cron run, // data is once stored and subsequently retreived from the // static $messages variable. // $message buffer is node and language specific. static $messages = array(); // By default the the node is send which is supplied in the function call. // When translation is used, the availability of translations is checked // and when available the translation of the preferred language is selected. $nid = $context['node']->nid; $langcode = $message['language']->language; if (module_exists('translation')) { // If the node has translations and a translation is required // the equivalent of the node in the required langugage is used // or the base node (nid == tnid) is used. if ($tnid = $context['node']->tnid) { if ($langcode != $context['node']->language) { $translations = translation_node_get_translations($tnid); // A translation is available in the preferred language. if ($translation = $translations[$langcode]) { $nid = $translation->nid; $langcode = $translation->language; } else { // No translation found which matches the preferred language. foreach ($translations as $translation) { if ($translation->nid == $tnid) { $nid = $tnid; $langcode = $translation->language; break; } } } } } // If a translation of the node is used and this node is not available in // the message buffer, then load this node. if ($nid != $context['node']->nid && !isset($messages[$nid][$langcode])) { $context['node'] = node_load($nid); } } if (!isset($messages[$nid][$langcode])) { $node = $context['node']; // Add simplenews specific header data $headers = array_merge($message['headers'], _simplenews_headers($node, $params['from']['address'])); $headers['From'] = $params['from']['formatted']; $message['headers'] = $messages[$nid][$langcode]['headers'] = $headers; // Build email subject if ($tid = $node->simplenews['tid']) { $term = taxonomy_get_term($tid); // Translate the newsletter term name if simplenews vocabulary uses Localized terms. if (module_exists('i18ntaxonomy') && i18ntaxonomy_vocabulary(variable_get('simplenews_vid', '')) == I18N_TAXONOMY_LOCALIZE) { $name = check_plain(tt('taxonomy:term:'. $tid .':name', $term->name, $langcode)); } else { $name = check_plain($term->name); } } else { $name = t('Unassigned newsletter'); } $subject = theme('simplenews_newsletter_subject', $name, check_plain($node->title), $message['language']); $subject = str_replace(array("\r", "\n"), '', $subject); $message['subject'] = $messages[$nid][$langcode]['subject'] = $subject; // Build message body // Processing node body mimics node_view() with full node view $node = node_build_content($node, FALSE, TRUE); $content = drupal_render($node->content); $node->body = $content; unset($node->teaser); node_invoke_nodeapi($node, 'alter', FALSE, TRUE); $body = theme('simplenews_newsletter_body', $node->body, check_plain($node->title), $message['language']); // Buffer body text node and language specific $messages[$nid][$langcode]['body'] = $body; } else { // Get message data from buffer $message['headers'] = $messages[$nid][$langcode]['headers']; $message['subject'] = $messages[$nid][$langcode]['subject']; $body = $messages[$nid][$langcode]['body']; } // Build message body. // The placeholders are replaced with user specific data // before conversion to plain text. $variables = user_mail_tokens($context['account'], $context['account']->language); $body = strtr($body, $variables); if ($context['node']->simplenews['s_format'] == 'plain') { $body = simplenews_html_to_text($body); } $message['body']['body'] = $body; // Build message footer. if ($key == 'node' && isset($context['account']->snid)) { $hash = _simplenews_generate_hash($context['account']->mail, $context['account']->snid, $context['node']->simplenews['tid']); } else { $hash = ''; } $message['body']['footer'] = theme('simplenews_newsletter_footer', $context['node']->simplenews['s_format'], $hash, $key == 'test', $message['language']); // Add user specific header data. $message['headers']['List-Unsubscribe'] = '<'. url('newsletter/confirm/remove/'. $hash, array('absolute' => TRUE)) .'>'; break; case 'subscribe': // Use formatted from address "name" $message['headers']['From'] = $params['from']['formatted']; if (isset($context['account']->snid) && isset($params['newsletter']->tid)) { $hash = _simplenews_generate_hash($context['account']->mail, $context['account']->snid, $params['newsletter']->tid); } else { $hash = NULL; } $variables = user_mail_tokens($context['account'], $context['account']->language); $variables += array('!confirmation_url' => url('newsletter/confirm/add/'. $hash, array('absolute' => TRUE))); $variables += array('!newsletter' => $params['newsletter']->name); $message['subject'] = _simplenews_subscription_confirmation_text('subscribe_subject', $context['account']->language, $variables); if (simplenews_user_is_subscribed($context['account']->mail, $params['newsletter']->tid)) { $message['body'] = _simplenews_subscription_confirmation_text('subscribe_subscribed', $context['account']->language, $variables); } else { $message['body'] = _simplenews_subscription_confirmation_text('subscribe_unsubscribed', $context['account']->language, $variables); } break; case 'unsubscribe': // Use formatted from address "name" $message['headers']['From'] = $params['from']['formatted']; if (isset($context['account']->snid) && isset($params['newsletter']->tid)) { $hash = _simplenews_generate_hash($context['account']->mail, $context['account']->snid, $params['newsletter']->tid); } else { $hash = NULL; } $variables = user_mail_tokens($context['account'], $context['account']->language); $variables += array('!confirmation_url' => url('newsletter/confirm/remove/'. $hash, array('absolute' => TRUE))); $variables += array('!newsletter' => $params['newsletter']->name); $message['subject'] = _simplenews_subscription_confirmation_text('subscribe_subject', $context['account']->language, $variables); if (simplenews_user_is_subscribed($context['account']->mail, $params['newsletter']->tid)) { $message['body'] = _simplenews_subscription_confirmation_text('unsubscribe_subscribed', $context['account']->language, $variables); } else { $message['body'] = _simplenews_subscription_confirmation_text('unsubscribe_unsubscribed', $context['account']->language, $variables); } break; } // Debug message to check for outgoing emails messages. // Newsletters ($key = 'node') are not send now. Debugging will take place in simplenews_mail_send() when the newsletters are send if (variable_get('simplenews_debug', FALSE) && $key != 'node') { watchdog('simplenews', 'Outgoing email. Message type: %type
Subject: %subject
Recipient: %to', array('%type' => $key, '%to' => $message['to'], '%subject' => $message['subject']), WATCHDOG_DEBUG); } } /** * Send simplenews newsletters from the spool. * * Iindividual newsletter emails are stored in database spool. * Sending is triggered by cron or immediately when the node is saved. * Mail data is retreived from the spool, rendered and send one by one * If sending is succesful the message is marked as send in the spool. */ function simplenews_mail_send($nid = NULL, $vid = NULL, $limit = NULL) { // Send pending messages from database cache // A limited number of mails is retrieved from the spool $limit = isset($limit) ? $limit : variable_get('simplenews_throttle', 20); if ($messages = simplenews_mail_spool_get(SIMPLENEWS_SPOOL_PENDING, $nid, $vid, $limit)) { $mail_sent = array(); foreach ($messages as $key => $message) { // Get subscription data for recipient and language $account = new stdClass(); $account->mail = $message['mail']; $subscription = simplenews_get_subscription($account); $params['context']['account'] = $subscription; // Get node data for the mail $node = node_load(array('nid' => $message['nid'], 'vid' => $message['vid'])); $params['from'] = _simplenews_set_from($node); $params['context']['node'] = $node; // Send mail $message = drupal_mail('simplenews', 'node', $subscription->mail, $subscription->language, $params, $params['from']['address'], TRUE); if (variable_get('simplenews_debug', FALSE)) { watchdog('simplenews', 'Outgoing email. Message type: %type
Subject: %subject
Recipient: %to', array('%type' => 'node', '%to' => $message['to'], '%subject' => $message['subject']), WATCHDOG_DEBUG); } // Succesfull mail messages are marked in the spool with status send. // Succesfull mail are recorded with their spool id. if ($message['result']) { $mail_sent[] = $key; } } // Mark messages in the spool as sent and update newsletter status. if (!empty($mail_sent)) { simplenews_mail_spool_update($mail_sent, SIMPLENEWS_SPOOL_SEND); } simplenews_send_status_update(); } } /** * Store mail message in mail cache table. * * @param array $message data array to be stored * $message['mail'] * $message['nid'] * $message['vid'] * $message['tid'] * $message['status'] (Default: 1 = pending) * $message['time'] (default: current unix timestamp) * @param array $message Mail message array */ function simplenews_mail_spool_set($message) { $status = isset($message['status']) ? $message['status'] : SIMPLENEWS_SPOOL_PENDING; $time = isset($message['time']) ? $message['time'] : time(); db_query("INSERT INTO {simplenews_mail_spool} (mail, nid, vid, tid, status, timestamp) VALUES ('%s', %d, %d, %d, %d, %d)", $message['mail'], $message['nid'], $message['vid'], $message['tid'], $status, $time); } /** * Retreive data from mail spool * * @param string $status Status of data to be retreived (0 = hold, 1 = pending, 2 = send) * @param integer $nid node id * @param integer $vid node version id * @param integer $limit The maximum number of mails to load from the spool * * @return array Mail message array * $message['msid'] * $message['mail'] * $message['nid'] * $message['vid'] * $message['tid'] * $message['status'] * $message['time'] */ function simplenews_mail_spool_get($status, $nid = NULL, $vid = NULL, $limit = 999999) { $result = db_query_range("SELECT * FROM {simplenews_mail_spool} s WHERE s.status = %d ORDER BY s.timestamp ASC", $status, 0, $limit); while ($data = db_fetch_array($result)) { $message = array(); foreach ($data as $key => $value) { $message[$key] = $value; } $messages[$data['msid']] = $message; } return $messages; } /** * Update status of mail data in spool table. * * Time stamp is set to current time. * * @param array $msids Mail spool id of record to be updated * @param string $status New status (0 = hold, 1 = pending, 2 = send) */ function simplenews_mail_spool_update($msids, $status) { db_query("UPDATE {simplenews_mail_spool} SET status = %d, timestamp = %d WHERE msid IN (%s)", $status, time(), implode(',', $msids)); } /** * Count data in mail spool table. * * @param integer $nid newsletter node id * @param integer $vid newsletter revision id * @param string $status email send status * * @return array Mail message array */ function simplenews_mail_spool_count($nid, $vid, $status = SIMPLENEWS_SPOOL_PENDING) { return db_result(db_query("SELECT COUNT(*) FROM {simplenews_mail_spool} WHERE nid = %d AND vid = %d AND status = %d", $nid, $vid, $status)); } /** * Remove records from mail spool table. * * All records with status 'send' and time stamp before the expiration date * are removed from the spool. */ function simplenews_clear_spool() { $expiration_time = time() - variable_get('simplenews_spool_expire', 0) * 86400; db_query("DELETE FROM {simplenews_mail_spool} WHERE status = %d AND timestamp <= %d", SIMPLENEWS_SPOOL_SEND, $expiration_time); } /** * Update newsletter send status. * * Set newsletter send status based on email send status in spool table. * Translated and untranslated nodes get a different treatment. * * The spool table holds data for emails to be send and (optionally) * already send emails. The simplenews_newsletters table contains the overall * send status of each newsletter issue (node). * Newsletter issues get the status pending when sending is innitiated. As * long as unsend emails exist in the spool, the status of the newsletter remains * unsend. When no pending emails are found the newsletter status is set 'send'. * * Translated newsletters are a group of nodes that share the same tnid ({node}.tnid). * Only one node of the group is found in the spool, but all nodes should share * the same state. Therefore they are checked for the combined number of emails * in the spool. */ function simplenews_send_status_update() { $counts = array(); // number pending of emails in the spool $sum = array(); // sum of emails in the spool per tnid (translation id) $send = array(); // nodes with the status 'send' // For each pending newsletter count the number of pending emails in the spool. $result = db_query("SELECT s.nid, s.vid, s.tid, n.tnid FROM {simplenews_newsletters} s JOIN {node} n ON s.nid = n.nid AND s.vid = n.vid WHERE s.s_status = %d", SIMPLENEWS_STATUS_SEND_PENDING); while ($newsletter = db_fetch_object($result)) { // nid-vid are combined in one unique key. $counts[$newsletter->tnid][$newsletter->nid .'-'. $newsletter->vid] = simplenews_mail_spool_count($newsletter->nid, $newsletter->vid); } // Determine which nodes are send per translation group and per individual node. foreach ($counts as $tnid => $node_count) { // The sum of emails per tnid is the combined status result for the group of translated nodes. // Untranslated nodes have tnid == 0 which will be ignored later. $sum[$tnid] = array_sum($node_count); foreach ($node_count as $nidvid => $count) { // Translated nodes (tnid != 0) if ($tnid != '0' && $sum[$tnid] == '0') { $send[] = $nidvid; } // Untranslated nodes (tnid == 0) elseif ($tnid == '0' && $count == '0') { $send[] = $nidvid; } } } // Update overall newsletter status if (!empty($send)) { foreach ($send as $nidvid) { // Split the combined key 'nid-vid' $nid = strtok($nidvid, '-'); $vid = strtok('-'); db_query("UPDATE {simplenews_newsletters} SET s_status = '%s' WHERE nid = %d AND vid = %d", SIMPLENEWS_STATUS_SEND_READY, $nid, $vid); } } } /** * Implementations of hook_views_api(). */ function simplenews_views_api() { return array( 'api' => 2, ); } /** * Call simplenews actions. */ function simplenews_call_actions($op, $subscription) { // Only call actions when the simplenews_action module is enabled. if (!module_exists('simplenews_action')) { return; } $aids = _trigger_get_hook_aids('simplenews', $op); $context = array( 'hook' => 'simplenews', 'op' => $op, 'account' => $subscription, ); foreach ($aids as $aid => $action_info) { actions_do($aid, $subscription, $context); } } /** * Build formatted from-name and email for a mail object. * * Each newsletter (serie; tid) can have a different from address. * The from name and address depend on the newsletter term tid which is included in the $node object * * @param object $node Node object of a simplenews newsletter * * @return array [address] = from address; [formatted] = formatted from name and address */ function _simplenews_set_from($node = NULL) { $address_default = variable_get('site_mail', ini_get('sendmail_from')); $name_default = variable_get('site_name', 'Drupal'); if (isset($node->simplenews['tid'])) { $address = variable_get('simplenews_from_address_'. $node->simplenews['tid'], variable_get('simplenews_from_address', $address_default)); $name = variable_get('simplenews_from_name_'. $node->simplenews['tid'], variable_get('simplenews_from_name', $name_default)); } else { $address = variable_get('simplenews_from_address', $address_default); $name = variable_get('simplenews_from_name', $name_default); } return array( 'address' => $address, 'formatted' => '"'. mime_header_encode(addslashes(check_plain($name))) .'" <'. $address .'>', ); } /** * Build header array with priority and receipt confirmation settings. * * @param $node: node object * @param $from: from email address * * @return Header array with priority and receipt confirmation info */ function _simplenews_headers($node, $from) { $headers = array(); // If receipt is requested, add headers. if ($node->simplenews['receipt']) { $headers['Disposition-Notification-To'] = $from; $headers['X-Confirm-Reading-To'] = $from; } // Add priority if set. switch ($node->simplenews['priority']) { case SIMPLENEWS_PRIORITY_HIGHEST: $headers['Priority'] = 'High'; $headers['X-Priority'] = '1'; $headers['X-MSMail-Priority'] = 'Highest'; break; case SIMPLENEWS_PRIORITY_HIGH: $headers['Priority'] = 'urgent'; $headers['X-Priority'] = '2'; $headers['X-MSMail-Priority'] = 'High'; break; case SIMPLENEWS_PRIORITY_NORMAL: $headers['Priority'] = 'normal'; $headers['X-Priority'] = '3'; $headers['X-MSMail-Priority'] = 'Normal'; break; case SIMPLENEWS_PRIORITY_LOW: $headers['Priority'] = 'non-urgent'; $headers['X-Priority'] = '4'; $headers['X-MSMail-Priority'] = 'Low'; break; case SIMPLENEWS_PRIORITY_LOWEST: $headers['Priority'] = 'non-urgent'; $headers['X-Priority'] = '5'; $headers['X-MSMail-Priority'] = 'Lowest'; break; } // Add general headers $headers['Precedence'] = 'bulk'; return $headers; } /** * HTML to text conversion for HTML and special characters. * * Converts some special HTMLcharacters in addition to drupal_html_to_text() * * @param string $text Source text with HTML and special characters * * @return string Target text with HTML and special characters replaced */ //TODO: convert url to absolute url's with (right prefix ?) function simplenews_html_to_text($text) { // Remove in-page links $pattern = '@]+?href="#[^"]*"[^>]*?>(.+?)@i'; $text = preg_replace($pattern, '$1', $text); // Replace some special characters before performing the drupal standard conversion $preg = _simplenews_html_replace(); $text = preg_replace(array_keys($preg), array_values($preg), $text); // Perform standard drupal html to text conversion return drupal_html_to_text($text); } /** * List of preg* regular expression patterns to search for and replace with */ function _simplenews_html_replace() { return array( '/"/i' => '"', '/>/i' => '>', '/</i' => '<', '/&/i' => '&', '/©/i' => '(c)', '/™/i' => '(tm)', '/“/' => '"', '/”/' => '"', '/–/' => '-', '/’/' => "'", '/&/' => '&', '/©/' => '(c)', '/™/' => '(tm)', '/—/' => '--', '/“/' => '"', '/”/' => '"', '/•/' => '*', '/®/i' => '(R)', '/•/i' => '*', '/€/i' => 'Euro ', ); } /** * Replace tokens in node body/teaser with user specific variables. */ function simplenews_replace_vars($node, $teaser = TRUE) { global $user; $variables = user_mail_tokens($user, $user->language); $node->body = strtr($node->body, $variables); if ($teaser) { $node->teaser = strtr($node->teaser, $variables); } return $node; } /** * Create a 32 character identifier. */ function simplenews_private_key() { $key = variable_get('simplenews_private_key', FALSE); if (!$key) { // This will create a 32 character identifier (a 128 bit hex number) that is extremely difficult to predict $key = md5(uniqid(rand())); variable_set('simplenews_private_key', $key); } return $key; } /** * Implementation of hook_help(). */ function simplenews_help($path, $arg) { switch ($path) { case 'admin/help#simplenews': $help = "

". t('Simplenews publishes and sends newsletters to lists of subscribers. Both anonymous and authenticated users can opt-in to different mailing lists.') ."

\n"; $help .= "

". t('Simplenews uses nodes for newsletter issues. Each newsletter issue is assigned to one newsletter by a taxonomy term. Node type and vocabulary are selectable. A newsletter is send to all email addresses which are subscribed to the newsletter. Newsletter issues can be sent only once. Large mailings should be sent by cron to spread the load of the mailserver.') ."

\n"; $help .= "

". t('Simplenews adds elements to the newsletter node add/edit form to manage newsletter format and sending of the newsletter issue. A newsletter issue can be sent for test before sending officially.') ."

\n"; $help .= "

". t('Both anonymous and authenticated users can opt-in and opt-out to a newsletter. A confirmation message is sent to anonymous users at subscription and unsubscription. Users can (un)subscribe using a form and a block. A subscription block is available for each newsletter offering a subscription form, a link to recent newsletters and RSS feed. Email addresses can also be imported and exported via the subscription administration pages.') ."

\n"; $help .= "

". t('Configuration') ."

\n"; $help .= "
    "; if (user_access('administer permissions')) { $help .= "
  • ". l(t('Configure permissions'), 'admin/user/permissions', array('fragment' => 'module-simplenews')) ."
  • \n"; } if (user_access('administer simplenews settings')) { $help .= "
  • ". l(t('Configure Simplenews'), 'admin/settings/simplenews') ."
  • \n"; } if (user_access('administer blocks')) { $help .= "
  • ". t('Enable a newsletter subscription block.', array('@admin_blocks' => url('admin/build/block'))) ."
  • \n"; } if (user_access('administer simplenews settings')) { $help .= "
  • ". t('Manage your newsletters, sent newsletters and subscriptions.', array('@newsletters' => url('admin/content/simplenews/types'), '@sent' => url('admin/content/simplenews'), '@subscriptions' => url('admin/content/simplenews/users'))) ."
  • \n"; } $help .= "
"; $help .= "

". t('For more information, see the online handbook entry for Simplenews.', array('@handbook', 'http://drupal.org/node/197057')) ."

\n"; return $help; case 'node/add/simplenews': $help = '
    '; $help .= "
  • ". t('Add this newsletter issue to a newsletter by selecting a newsletter from the select list. Send a newsletter or a test newsletter by selecting the appropriate radio button and submitting the node.') ."
  • \n"; if (user_access('administer simplenews settings')) { $help .= "
  • ". t('Set default send options at Administer > Site configuration > Simplenews > Newsletter.', array('@configuration' => url('admin/settings/simplenews/newsletter'))) ."
  • \n"; } if (user_access('administer newsletters')) { $help .= "
  • ". t('Set newsletter specific options at Administer > Content management > Newsletters > Newsletters.', array('@configuration' => url('admin/content/simplenews/types'))) ."
  • \n"; } $help .= "
"; return $help; case 'admin/settings/simplenews/newsletter': $help = '
    '; $help .= '
  • '. t('These settings are default to all newsletters. Newsletter specific settings can be found at the newsletter\'s settings page.', array('@page' => url('admin/content/simplenews/types'))) ."
  • \n"; if (!module_exists('mimemail')) { $help .= "
  • ". t('Install Mime Mail to send HTML emails or emails with attachments (both plain text and HTML).', array('@mime_mail_url' => 'http://drupal.org/project/mimemail')) ."
  • \n"; } $help .= "
"; return $help; case 'admin/content/simplenews/types/add': $help = '

'. t('You can create different newsletters (or subjects) to categorize your news (e.g. Cats news, Dogs news, ...).') ."

\n"; return $help; } } /** * Generate the hash key used for subscribe/unsubscribe link. */ function _simplenews_generate_hash($mail, $snid, $tid) { return drupal_substr(md5($mail . simplenews_private_key()), 0, 10) . $snid .'t'. $tid; } /** * Determine possible mail format options. * * The mime_mail module must be installed to send HTML mails. */ function _simplenews_format_options() { $options = array('plain' => t('plain')); if (module_exists('mimemail')) { $options['html'] = t('html'); } return $options; } /** * Generate default and custom subscription confirmation email text. * * @param string $key text identification key * @param object $language language object * @param array $variables array of variables as used by t() */ function _simplenews_subscription_confirmation_text($key, $language = NULL, $variables = array()) { $langcode = isset($language) ? $language->language : NULL; if ($admin_setting = variable_get('simplenews_confirm_'. $key, FALSE)) { // An admin setting overrides the default string. return t($admin_setting, $variables, $langcode); } else { // No override, return default string. switch ($key) { case 'subscribe_unsubscribed': return t("We have received a request for subscription of !mailto to the !newsletter on !site website at !uri. To confirm this subscription please use the link below.\n\n!confirmation_url", $variables, $langcode); case 'subscribe_subscribed': return t("We have received a request for subscription of !mailto to the !newsletter on !site website at !uri. However, this email is already subscribed to this newsletter. If you intended to unsubscribe please visit our site: !uri", $variables, $langcode); case 'unsubscribe_subscribed': return t("We have received a request to unsubscribe !mailto from the !newsletter on !site website at !uri. To confirm this unsubscription please use the link below.\n\n!confirmation_url", $variables, $langcode); case 'unsubscribe_unsubscribed': return t("We have received a request to unsubscribe !mailto from the !newsletter on !site website at !uri. However, this email is not subscribed to this newsletter. If you intended to subscribe please visit our site: !uri", $variables, $langcode); case 'subscribe_subject': return t("Confirmation for !newsletter from !site", $variables, $langcode); } } } /** * Implementation of hook_theme. */ function simplenews_theme() { return array( 'simplenews_block' => array( 'template' => 'simplenews-block', 'arguments' => array('tid' => NULL), ), 'simplenews_status' => array( 'template' => 'simplenews-status', 'file' => 'simplenews.admin.inc', 'arguments' => array('status' => NULL, 'source' => NULL), ), 'simplenews_newsletter' => array( 'arguments' => array('node' => NULL, 'tid' => NULL), ), 'simplenews_newsletter_subject' => array( 'arguments' => array('name' => NULL, 'title' => NULL, 'language' => NULL), ), 'simplenews_newsletter_body' => array( 'arguments' => array('body' => NULL, 'title' => NULL, 'language' => NULL), ), 'simplenews_newsletter_footer' => array( 'arguments' => array('format' => NULL, 'hash' => NULL, 'test' => NULL, 'language' => NULL), ), 'simplenews_subscription_list' => array( 'file' => 'simplenews.admin.inc', 'arguments' => array('form' => NULL), ), ); } /** * Process variables to format the simplenews block. * * Collect data and apply access restrictions. * * $variables contains: * - $tid * * @see simplenews-block.tpl.php * @see theme_simplenews-block() */ function template_preprocess_simplenews_block(&$variables) { global $user; $tid = $variables['tid']; // Set default values in case of missing permission. $variables['form'] = ''; $variables['subscription_link'] = ''; $variables['newsletter_link'] = ''; $variables['issue_list'] = ''; $variables['rssfeed'] = ''; // Block content variables $variables['message'] = check_plain(variable_get('simplenews_block_m_'. $tid, t('Stay informed on our latest news!'))); if (user_access('subscribe to newsletters')) { $variables['form'] = drupal_get_form('simplenews_block_form_'. $tid); $variables['subscription_link'] = l(t('Manage my subscriptions'), 'newsletter/subscriptions'); } if (user_access('view links in block') || user_access('administer newsletters')) { $variables['newsletter_link'] = l(t('Previous issues'), 'taxonomy/term/'. $tid); $recent = simplenews_recent_newsletters($tid, variable_get('simplenews_block_i_'. $tid, 5)); $variables['issue_list'] = theme('item_list', $recent, t('Previous issues'), 'ul'); $term = taxonomy_get_term($tid); $variables['rssfeed'] = theme('feed_icon', url('taxonomy/term/'. $tid .'/0/feed'), t('@newsletter feed', array('@newsletter' => $term->name))); } // Block content control variables $variables['use_form'] = variable_get('simplenews_block_f_'. $tid, 1); $variables['use_issue_link'] = variable_get('simplenews_block_l_'. $tid, 1); $variables['use_issue_list'] = variable_get('simplenews_block_i_status_'. $tid, 0); $variables['use_rss'] = variable_get('simplenews_block_r_'. $tid, 1); // Additional variables $variables['subscribed'] = empty($user->uid) ? FALSE : (simplenews_user_is_subscribed($user->mail, $tid) == TRUE); $variables['user'] = !empty($user->uid); } /** * Theme the newsletter message subject and body. */ function theme_simplenews_newsletter($node, $tid) { $term = taxonomy_get_term($tid); $name = $term->name ? $term->name : t('Unassigned newsletter'); $node->subject = '['. $name .'] '. $node->title; $node->body = '

'. $node->title ."

\n". $node->body; return $node; } /** * Theme the newsletter email subject. */ function theme_simplenews_newsletter_subject($name, $title, $language) { return '['. $name .'] '. $title; } /** * Theme the newsletter message body. */ function theme_simplenews_newsletter_body($body, $title, $language) { $output = '

'. $title ."

\n"; $output .= $body; return $output; } /** * Theme the newsletter message footer. */ function theme_simplenews_newsletter_footer($format, $hash, $test = FALSE, $language) { if ($format == 'html') { $output = ''; } else { $output = "\n\n-- \n". t('Unsubscribe from this newsletter: !url', array('!url' => url('newsletter/confirm/remove/'. $hash, array('absolute' => TRUE, 'language' => $language))), $language->language); } if ($test) { $output .= "\n- - - ". t('This is a test version of the newsletter. The above unsubscribe link does not work!', array(), $language->language) .' - - -'; } return $output; }