Simplenews settings.', array( '@settings' => url('admin/settings/simplenews/general') )), 'error'); } } /** * Implementation of hook_menu(). */ function simplenews_menu() { $items['admin/content/simplenews'] = array( 'title' => 'Newsletters Management', 'description' => 'Manage newsletters and subscriptions.', 'type' => MENU_NORMAL_ITEM, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_news'), 'access callback' => 'simplenews_newsletter_access', 'file' => 'includes/simplenews.admin.inc', ); $items['admin/content/simplenews/sent'] = array( 'title' => 'Issues', 'description' => 'List of newsletter issues.', 'type' => MENU_DEFAULT_LOCAL_TASK, 'access callback' => 'user_access', 'access arguments' => array('administer newsletters'), 'weight' => -10, ); $items['admin/content/simplenews/types'] = array( 'title' => 'Newsletters', 'description' => 'List, add and edit newsletter series.', 'type' => MENU_LOCAL_TASK, 'page callback' => 'simplenews_types_overview', 'access callback' => 'user_access', 'access arguments' => array('administer newsletters'), 'file' => 'includes/simplenews.admin.inc', 'weight' => -8, ); $items['admin/content/simplenews/types/edit/%'] = array( 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_types_form', 5), 'access arguments' => array('administer newsletters'), 'file' => 'includes/simplenews.admin.inc', ); $items['admin/content/simplenews/types/delete/%'] = array( 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_types_delete', 5), 'access arguments' => array('administer newsletters'), 'file' => 'includes/simplenews.admin.inc', ); $items['admin/content/simplenews/types/list'] = array( 'title' => 'List newsletters', 'type' => MENU_DEFAULT_LOCAL_TASK, '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' => 'includes/simplenews.admin.inc', 'weight' => -9, ); $items['admin/content/simplenews/subscriptions/delete'] = array( 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_subscription_multiple_delete_confirm'), 'access callback' => 'user_access', 'access arguments' => array('administer simplenews subscriptions'), 'file' => 'includes/simplenews.admin.inc', ); $items['admin/content/simplenews/users'] = array( 'title' => 'Subscriptions', 'description' => 'Newsletter subscription management.', 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_subscription_admin'), 'access callback' => 'user_access', 'access arguments' => array('administer simplenews subscriptions'), 'file' => 'includes/simplenews.admin.inc', 'weight' => -7, ); $items['admin/content/simplenews/users/edit/%'] = array( 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_subscriptions_admin_form', 5), 'access arguments' => array('administer simplenews subscriptions'), 'file' => 'includes/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 simplenews subscriptions'), 'file' => 'includes/simplenews.admin.inc', 'weight' => -9, ); $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 simplenews subscriptions'), 'file' => 'includes/simplenews.admin.inc', 'weight' => -7, ); $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 simplenews subscriptions'), 'file' => 'includes/simplenews.admin.inc', 'weight' => -8, ); $items['admin/settings/simplenews'] = array( 'title' => 'Simplenews settings', 'description' => 'Manage simplenews configuration.', 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_settings'), 'access arguments' => array('administer simplenews settings'), 'file' => 'includes/simplenews.admin.inc', ); $items['admin/settings/simplenews/general'] = array( 'title' => 'General', 'description' => 'Simplenews content type and vocabulary settings.', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10, ); $items['admin/settings/simplenews/newsletter'] = array( 'title' => 'Defaults', 'description' => 'Newsletter default settings and sender data.', 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_settings_newsletter'), 'access arguments' => array('administer simplenews settings'), 'file' => 'includes/simplenews.admin.inc', 'weight' => -9, ); $items['admin/settings/simplenews/subscription'] = array( 'title' => 'Subscriptions', 'description' => 'Subscription settings, opt-in/out confirmation email text.', 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_settings_subscription'), 'access arguments' => array('administer simplenews settings'), 'file' => 'includes/simplenews.admin.inc', 'weight' => -8, ); $items['admin/settings/simplenews/mail'] = array( 'title' => 'Send mail', 'description' => 'Send mail, cron and debug options.', 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_admin_settings_mail'), 'access arguments' => array('administer simplenews settings'), 'file' => 'includes/simplenews.admin.inc', 'weight' => -7, ); $items['newsletter/confirm'] = array( 'type' => MENU_CALLBACK, 'page callback' => 'simplenews_confirm_subscription', 'access callback' => TRUE, 'file' => 'includes/simplenews.subscription.inc', ); $items['newsletter/subscriptions'] = array( 'title' => 'Newsletter subscriptions', 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('simplenews_subscriptions_page_form'), 'access arguments' => array('subscribe to newsletters'), 'file' => 'includes/simplenews.subscription.inc', ); $items['node/%node/simplenews'] = array( 'title' => 'Newsletter', 'type' => MENU_LOCAL_TASK, 'access callback' => 'simplenews_node_tab_access', 'access arguments' => array(1), 'page callback' => 'simplenews_node_tab_page', 'page arguments' => array(1), 'weight' => 2, ); return $items; } /** * Menu item access callback. * * Access for both newsletter and subscriber admins. */ function simplenews_newsletter_access() { return user_access('administer newsletters') || user_access('administer simplenews subscriptions'); } /** * Menu item access callback. * * Access for Node Tab */ function simplenews_node_tab_access($node = NULL) { $simplenews_types = variable_get('simplenews_content_types', array('simplenews')); if (in_array($node->type, $simplenews_types) && user_access('send newsletter')) { return TRUE; } else { return FALSE; } } /** * Menu callback. Displays newsletter-related stuff of a node. */ function simplenews_node_tab_page($node = NULL) { $output .= drupal_get_form('simplenews_node_tab_send_form', $node); return $output; } /** * Simplenews tab form */ function simplenews_node_tab_send_form($form_state, $node) { // Prepare $simplenews_values = _simplenews_get_node_defaults(); if (isset($node->simplenews) && !empty($node->simplenews)) { $simplenews_values = $node->simplenews; } // Flatten the values for e.g. preview to make them accessible same as default and load. $simplenews_values = _simplenews_flatten_array($simplenews_values); $form = array(); // We will need the node $form['nid'] = array( '#type' => 'hidden', '#value' => $node->nid, ); $form['simplenews'] = array( '#type' => 'fieldset', '#title' => t('Send newsletter'), '#collapsible' => TRUE, '#collapsed' => FALSE, // We need #tree to persist key 'simplenews' in submissions '#tree' => TRUE, ); // Add tid $vid = variable_get('simplenews_vid', ''); foreach($node->taxonomy as $tid => $term) { if ($term->vid == $vid) { $form['simplenews']['tid'] = array( '#type' => 'hidden', '#value' => $term->tid, ); break; } } // 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)) { $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('Send action'), '#default_value' => variable_get('simplenews_send', SIMPLENEWS_COMMAND_SEND_TEST), '#options' => $options, '#attributes' => array('class' => 'simplenews-command-send'), ); $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), ); } $form['simplenews']['advanced'] = array( '#type' => 'fieldset', '#title' => t('Email options'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); // 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']['advanced']['s_format'] = array( '#type' => 'select', '#title' => t('Email format'), '#default_value' => isset($simplenews_values['s_format']) ? $simplenews_values['s_format'] : variable_get('simplenews_format', 'plain'), '#options' => _simplenews_format_options(), ); } else { $form['simplenews']['advanced']['s_format'] = array( '#type' => 'hidden', '#value' => key($format_options), ); } // include function that provides the priority values module_load_include('inc', 'simplenews', 'includes/simplenews.admin'); $form['simplenews']['advanced']['priority'] = array( '#type' => 'select', '#title' => t('Email priority'), '#default_value' => isset($simplenews_values['priority']) ? $simplenews_values['priority'] : variable_get('simplenews_priority', SIMPLENEWS_PRIORITY_NONE), '#options' => simplenews_get_priority(), ); $form['simplenews']['advanced']['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), ); } else { $form['simplenews']['none'] = array( '#type' => 'checkbox', '#return_value' => 0, '#attributes' => array('checked' => 'checked', 'disabled' => 'disabled'), ); $form['simplenews']['none']['#title'] = ($simplenews_values['s_status'] == SIMPLENEWS_STATUS_SEND_READY) ? t('This newsletter has been sent.') : t('This newsletter is pending.'); // We return now, because there's no point in having a submit button return $form; } $form['simplenews']['s_status'] = array( '#type' => 'hidden', '#value' => isset($simplenews_values['s_status']) ? $simplenews_values['s_status'] : SIMPLENEWS_STATUS_SEND_NOT, ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Submit'), ); return $form; } /** * Simplenews tab form validate callback */ function simplenews_node_tab_send_form_validate($form, &$form_state) { $values = $form_state['values']; if (isset($values['simplenews']['send']) && $values['simplenews']['send'] == SIMPLENEWS_COMMAND_SEND_TEST) { if (!empty($values['simplenews']['test_address'])) { $mails = explode(',', $values['simplenews']['test_address']); foreach ($mails as $mail) { $mail = trim($mail); if ($mail == '') { form_set_error('simplenews][test_address', t('Test email address is empty.')); } elseif (!simplenews_valid_email_address($mail)) { form_set_error('simplenews][test_address', t('Invalid email address %mail.', array('%mail' => $mail))); } } } else { form_set_error('simplenews][test_address', t('Missing test email address.')); } } } /** * Simplenews tab form submit callback */ function simplenews_node_tab_send_form_submit($form, &$form_state) { // Get the node $values = $form_state['values']; $node = node_load($values['nid']); $s_status = SIMPLENEWS_STATUS_SEND_NOT; if ($values['simplenews']['send'] == SIMPLENEWS_COMMAND_SEND_NOW) { $s_status = SIMPLENEWS_STATUS_SEND_PENDING; } $values['simplenews']['s_status'] = $s_status; // Is this a multilingual newsletter ? // When this node is selected for translation all translation of this node // will be sent too. // All translated nodes will receive the same send states (priority, confirmation, format). if (module_exists('translation') && translation_supported_type($node->type) && $node->tnid != 0) { if ($translations = translation_node_get_translations($node->tnid)) { foreach ($translations as $translation) { // translation_node_get_translation() only returns nid, title and language // For consistency, we load the full node $translation = node_load($translation->nid); simplenews_newsletter_update($translation, $values['simplenews']); } } else { simplenews_newsletter_update($node, $values['simplenews']); } } else { simplenews_newsletter_update($node, $values['simplenews']); } // Update $node before send $node->simplenews = _simplenews_flatten_array($values['simplenews']); // Send newsletter or test newsletter module_load_include('inc', 'simplenews', 'includes/simplenews.mail'); if ($values['simplenews']['send'] == SIMPLENEWS_COMMAND_SEND_NOW) { // Send newsletter to all subscribers simplenews_send_node($node); } elseif ($values['simplenews']['send'] == SIMPLENEWS_COMMAND_SEND_TEST) { // Send test newsletter to test address(es) simplenews_send_test($node); } } /** * Update {simplenews_newsletter} table * * @param node $node the current node (or translation) that should be updated * @param array $param the values which to update the newsletter with */ function simplenews_newsletter_update($node, $param = array()) { // Is there already a corresponding newsletter ? $sn_nid = db_result(db_query(" SELECT nid FROM {simplenews_newsletters} WHERE nid = %d", $node->nid )); if (!is_numeric($sn_nid)) { // No newsletter => we create it 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, $param['tid'], $param['s_status'], $param['advanced']['s_format'], $param['advanced']['priority'], $param['advanced']['receipt'] ); } else { // Already existing => we update it 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, $param['tid'], $param['s_status'], $param['advanced']['s_format'], $param['advanced']['priority'], $param['advanced']['receipt'], $node->nid ); } } /** * Implementation of hook_node_type(). * * Update 'simplenews_content_types' on node update and delete. * Related vocabulary settings are updated by taxonomy module. */ function simplenews_node_type($op, $info) { switch ($op) { case 'delete': $simplenews_types = variable_get('simplenews_content_types', array('simplenews')); if (isset($simplenews_types[$info->type])) { unset($simplenews_types[$info->type]); variable_set('simplenews_content_types', $simplenews_types); } break; case 'update': $simplenews_types = variable_get('simplenews_content_types', array('simplenews')); // apply nodetype rename if (isset($info->old_type) && isset($simplenews_types[$info->old_type]) && $info->old_type != $info->type) { unset($simplenews_types[$info->old_type]); $simplenews_types[$info->type] = $info->type; variable_set('simplenews_content_types', $simplenews_types); } break; } } /** * Implementation of hook_nodeapi(). */ function simplenews_nodeapi(&$node, $op, $teaser, $page) { global $user; // 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 'alter': // Don't replace the tokens when node alter is called by simplenews_mail. if (!isset($node->simplenews_mail)) { $tid = db_result(db_query(" SELECT s.tid FROM {simplenews_newsletters} s INNER JOIN {node} n ON s.nid = n.nid WHERE n.nid = %d", $node->nid)); global $language, $user; $context = array( 'node' => $node, // note the context represents the current user account for presentation. 'account' => $user, 'newsletter' => taxonomy_get_term($tid), ); // Check for function_exists to avoid fatal errors in 6--1 to 6--2 upgrade paths. if (isset($node->body) && function_exists('token_replace')) { $node->body = token_replace($node->body, 'simplenews', $context); } if (isset($node->teaser) && function_exists('token_replace')) { $node->teaser = token_replace($node->teaser, 'simplenews', $context); } } break; case 'validate': $vid = variable_get('simplenews_vid', ''); if (!isset($node->taxonomy[$vid]) || empty($node->taxonomy[$vid]) || simplenews_validate_taxonomy($node->taxonomy) == FALSE) { form_set_error('taxonomy', t('No newsletter term is selected, the newsletter taxonomy term is probably not configured correctly.
Check and save the Simplenews general settings.', array( '%name' => $vocabulary->name, '@settings' => url('admin/settings/simplenews/general') ))); } break; case 'insert': case 'update': // Initialize $node->simplenews in case it does not exist // (which should be the default case) if (empty($node->simplenews)) { $node->simplenews = db_fetch_array(db_query(' SELECT * FROM {simplenews_newsletters} WHERE nid = %d', $node->nid)); } if (empty($node->simplenews)) { $node->simplenews = _simplenews_get_node_defaults(); } // Get Simplenews vid $simplenews_vid = variable_get('simplenews_vid', ''); $node->simplenews['tid'] = $node->taxonomy[$simplenews_vid]; // Call the same update function as tab submit function simplenews_newsletter_update($node, $node->simplenews); 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))); } // Check if pending emails of this newsletter issue exist and delete these too. module_load_include('inc', 'simplenews', 'includes/simplenews.mail'); $count = simplenews_clear_spool_node($node); if ($count) { drupal_set_message(t('Newsletter %title was deleted but had @count pending emails. They can no longer be sent.', array( '%title' => $node->title, '@count' => $count, )), 'warning'); watchdog('simplenews', 'Newsletter %title deleted with @count pending emails. Emails can no longer be sent.', array( '%title' => $node->title, '@count' => $count, ), WATCHDOG_ALERT); } break; case 'load': // @todo: {simplenews_newsletters} data might be missing if an uninstall happened at some time with simplenews nodes created. provide reasonable defaults. $node->simplenews = db_fetch_array(db_query(' SELECT * FROM {simplenews_newsletters} WHERE nid = %d', $node->nid)); break; } } /** * 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 simplenews. */ 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; } } } elseif (is_object($term)) { $selected_terms[] = $term->tid; } elseif ($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, ); // We display the current content type settings in a disabled form element // to the user. The real value passed in the form separately because // disabled elements do not get saved at submit. $form['content_types']['display_only'] = $form['content_types']['nodes']; $form['content_types']['display_only']['#disabled'] = TRUE; $form['content_types']['display_only']['#description'] = t('These content type(s) are used as newsletter. They can be set in !simplenews_settings.', array( '!simplenews_settings' => l('Simplenews settings', 'admin/settings/simplenews') )); $form['content_types']['nodes'] = array( '#type' => 'value', '#value' => $form['content_types']['nodes']['#default_value'], ); // Free tagging can not be allowed see: simplenews_validate_taxonomy(). $form['settings']['tags'] = array('#type' => 'value', '#value' => FALSE); // Multiple select does not work with simplenews. $form['settings']['multiple'] = array('#type' => 'value', '#value' => FALSE); $form['settings']['required'] = array('#type' => 'value', '#value' => TRUE); } // Simplenews newsletter node form elseif (isset($form['type']) && isset($form['#node']) && strpos($form_id, '_node_form')) { if (in_array($form['type']['#value'], variable_get('simplenews_content_types', array('simplenews')))) { // 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. if (isset($form['body_field'])) { $form['body_field']['body']['#description'] = t("This will be the body of your newsletter. See 'Replacement patterns' for available variables.)"); } $form['simplenews_subscription']['subscription_mail']['token_help'] = array( '#title' => t('Replacement patterns'), '#type' => 'fieldset', '#collapsible' => TRUE, '#collapsed' => TRUE, '#weight' => -20, '#description' => t('These tokens can be used in all text fields and will be replaced on-screen and in the email. Note that simplenews-receiver tokens are not suitable for on-screen use.') ); $form['simplenews_subscription']['subscription_mail']['token_help']['help'] = array( '#value' => theme('token_help', 'simplenews'), ); $vocabulary = taxonomy_vocabulary_load(variable_get('simplenews_vid', '')); if (!empty($vocabulary) && !isset($vocabulary->nodes[$form['type']['#value']])) { drupal_set_message(t('Invalid vocabulary setting detected. Check and save the Simplenews general settings.', array( '%name' => $vocabulary->name, '@settings' => url('admin/settings/simplenews') )), 'error'); } } } } /** * Implementation of hook_cron(). */ function simplenews_cron() { module_load_include('inc', 'simplenews', 'includes/simplenews.mail'); simplenews_mail_spool(); simplenews_clear_spool(); // Update sent status for newsletter admin panel. simplenews_send_status_update(); } /** * 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 ($type) { case 'term': db_query(' DELETE FROM {simplenews_snid_tid} WHERE tid = %d', $term['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 'register': $options = $default_value = $hidden = array(); // Determine the newsletters to which a user can choose to subscribe. // Determine to which other newsletter a user is automatically subscribed. foreach (simplenews_get_newsletters(variable_get('simplenews_vid', ''), TRUE) as $newsletter) { $subscribe_new_account = variable_get('simplenews_new_account_' . $newsletter->tid, 'none'); $opt_inout_method = variable_get('simplenews_opt_inout_' . $newsletter->tid, 'double'); if (($subscribe_new_account == 'on' || $subscribe_new_account == 'off') && ($opt_inout_method == 'single' || $opt_inout_method == 'double')) { $options[$newsletter->tid] = check_plain($newsletter->name); $default_value[$newsletter->tid] = $subscribe_new_account == 'on' ? $newsletter->tid : 0; } else { if ($subscribe_new_account == 'silent' || ($subscribe_new_account == 'on' && $opt_inout_method == 'hidden')) { $hidden[] = $newsletter->tid; } } } $form = array(); if (count($options)) { $form['simplenews'] = array( '#type' => 'fieldset', '#title' => t('Newsletters'), '#description' => t('Select the newsletter(s) to which you wish to subscribe.'), '#weight' => 5, ); $form['simplenews']['newsletters'] = array( '#type' => 'checkboxes', '#options' => $options, '#default_value' => $default_value, ); } if (count($hidden)) { $form['simplenews_hidden'] = array( '#type' => 'hidden', '#value' => implode(',', $hidden), ); } return $form; break; case 'insert': // suppress login of different groups (e.g. logintoboggan) where mail address is not authenticated yet. Opt in/out settings are ignored in non-anonymous cases. // The user registration form may contain (hidden) form element to // subscribe to newsletters. Data of these elements are stored in // the $account->data variable. // We subscribe the user according to the (hidden) form elements. // take over previously anonymous subscribed 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); } // Process hidden (automatic) subscriptions. if (isset($edit['simplenews_hidden'])) { foreach (explode(',', $edit['simplenews_hidden']) as $tid) { simplenews_subscribe_user($account->mail, $tid, FALSE, 'automatically'); } } // Process subscription check boxes. if (isset($edit['newsletters'])) { foreach (array_keys(array_filter($edit['newsletters'])) as $tid) { simplenews_subscribe_user($account->mail, $tid, FALSE, 'website'); $newsletters = simplenews_get_newsletters(variable_get('simplenews_vid', ''), TRUE); drupal_set_message(t('You have been subscribed to %newsletter.', array('%newsletter' => $newsletters[$tid]->name))); } } // set inactive if not created by an administrator. this needs a cleaner API. if (!user_access('administer users')) { db_query(" UPDATE {simplenews_subscriptions} SET activated = %d WHERE uid = %d", 0, $account->uid); } break; case 'login': // is authenticated user: activate subscription db_query(" UPDATE {simplenews_subscriptions} SET activated = %d WHERE uid = %d", 1, $account->uid); break; case 'update': // always keep uid, mail, language in sync if ($category == 'account' && $edit['mail']) { $query = " SELECT snid FROM {simplenews_subscriptions} WHERE uid = %d"; if ($result = db_fetch_object(db_query($query, $account->uid))) { // user has snid. if user changes mail to previously subscribed anonymous mail, remove subscription. db_query(" DELETE FROM {simplenews_subscriptions} WHERE mail = '%s' AND uid = 0", $edit['mail']); // migrate current subscription snid to new mail, language. db_query(" UPDATE {simplenews_subscriptions} SET mail = '%s', language = '%s' WHERE snid = %d", $edit['mail'], $edit['language'], $result->snid); } else { // no current snid. try taking over subscription via user mail match. $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)) { // TODO: since we can't detect if a user is in mail verification process, we always enable // user subscriptions if user is active. this also matches for unverified users. // we should depend on a contrib module to detect this state and suppress activation. $activate = $edit['status']; db_query(" UPDATE {simplenews_subscriptions} SET activated = %d WHERE uid = %d", $activate, $account->uid); } } 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') { // This is reached only if op=categories access callback passed. module_load_include('inc', 'simplenews', 'includes/simplenews.mail'); $subscription = simplenews_get_subscription($account); module_load_include('inc', 'simplenews', 'includes/simplenews.subscription'); $form_state = array(); $form = simplenews_subscriptions_account_form($form_state, $account); return $form; } break; case 'categories': // Newsletter tab with custom permission check. $output[] = array( 'name' => 'newsletter', 'title' => t('My newsletters'), 'weight' => 10, 'access callback' => 'simplenews_subscription_edit_access', ); return $output; break; case 'view': global $user; if ($user->uid == $account->uid || user_access('administer users')) { $account->content['simplenews'] = array( '#type' => 'user_profile_category', '#title' => t('Newsletters'), ); // Collect newsletter to which the current user is subscribed. // 'hidden' newsletters are not listed. foreach (simplenews_get_newsletters(variable_get('simplenews_vid', '')) 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 AND t.status = %d', $account->uid, $newsletter->tid, SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED)) ) { $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', $account) || $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)) { $account->content['simplenews']['my_newsletters'] = array( '#type' => 'user_profile_item', '#value' => t('Manage my subscriptions', array( '!url' => url('user/' . $account->uid . '/edit/newsletter') )), '#weight' => -1, ); } } break; } } /** * Access callback for user newsletter editing. */ function simplenews_subscription_edit_access($account) { global $user; // Disallow anonymous. if (!$account || $account->uid==0) { return FALSE; } // Allow edit own subscription. if ($user->uid == $account->uid) { if (user_access('subscribe to newsletters', $account)) { return TRUE; } } // Allow administrator to edit account's subscription. if (user_access('administer users')) { return TRUE; } return FALSE; } /** * Implementation of hook_block(). */ function simplenews_block($op = 'list', $delta = 0, $edit = array()) { switch ($op) { case 'list': $blocks = array(); // Special block for multi $blocks[0] = array( 'info' => t('Newsletter: Multi Subscription'), ); foreach (simplenews_get_newsletters(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 // Only list a block if the newsletter is not hidden. $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': // Special block for multi if ($delta == 0) { $form['simplenews_block_multiple']['simplenews_block_m_multiple'] = array( '#type' => 'textfield', '#title' => t('Block message'), '#size' => 60, '#maxlength' => 128, // @todo: clean localization / i18n needed '#default_value' => variable_get('simplenews_block_m_multiple', t('Select the newsletter(s) to which you want to subscribe or unsubscribe.')), ); } else { $form['simplenews_block_' . $delta]['simplenews_block_m_' . $delta] = array( '#type' => 'textfield', '#title' => t('Block message'), '#size' => 60, '#maxlength' => 128, // @todo: clean localization / i18n needed '#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), ); $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), ); $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), ); } return $form; case 'save': //Special block for multi if ($delta == 0) { variable_set('simplenews_block_m_multiple', $edit['simplenews_block_m_multiple']); } else { 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': // Special block for multi if ($delta == 0) { if (user_access('subscribe to newsletters')) { module_load_include('inc', 'simplenews', 'includes/simplenews.subscription'); // render block only if permitted $block = array( 'subject' => t('Newsletters'), 'content' => theme('simplenews_multi_block'), ); return $block; } return NULL; } else { global $language; $newsletters = simplenews_get_newsletters(variable_get('simplenews_vid', '')); // Only display a block if $delta is a valid newsletter term id. if (in_array($delta, array_keys($newsletters))) { module_load_include('inc', 'simplenews', 'includes/simplenews.subscription'); // $delta is validated, the block can be displayed. $block = array( 'subject' => check_plain($newsletters[$delta]->name), 'content' => theme(array('simplenews_block__' . $delta, 'simplenews_block'), $delta), ); return $block; } } 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($form_id, $args) { $forms = array(); $match = preg_match('/simplenews_block_form_(\d+)/', $form_id, $matches); if ($match) { $forms['simplenews_block_form_' . $matches[1]] = array( 'callback' => 'simplenews_block_form', 'callback arguments' => array($matches[1]), ); } 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-mail. $account = new stdClass(); $account->uid = 0; $account->mail = $mail; } return $account; } /** * Update subscriber data. * * @param $snid * Subscribers ID. * @param $data * Array of data to be updated * 'language' Preferred newsletter language (default: '') */ function simplenews_subscriber_update($subscription, $data) { $data['snid'] = $subscription->snid; drupal_write_record('simplenews_subscriptions', $data, 'snid'); } /** * 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 * * This function does NOT update language information if account already exists. * * @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. * @param string $source * Indication for source of subscription. Simplenews uses these sources: * website: via any website form (with or without confirmation email) * mass subscribe: mass admin UI * mass unsubscribe: mass admin UI * action: Drupal actions * * @return $subscription */ function simplenews_subscribe_user($mail, $tid, $confirm = TRUE, $source = 'unknown', $preferred_language = NULL) { global $language; // 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, timestamp) VALUES ('%s', %d, '%s', %d, %d)", $mail, $account->uid, $preferred_language, 1, time()); $subscription = simplenews_get_subscription($account); } if ($confirm) { module_load_include('inc', 'simplenews', 'includes/simplenews.mail'); // 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['context']['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])) { // Add user to newsletter relationship if not already subscribed. // Check if user is (un)subscribed to this newsletter. // Resubscribe or add new subscription. if (isset($subscription->newsletter_subscription[$tid])) { db_query(" UPDATE {simplenews_snid_tid} SET status = %d, timestamp = %d, source = '%s' WHERE snid = %d AND tid = %d", SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED, time(), $source, $subscription->snid, $tid); } else { db_query(" INSERT INTO {simplenews_snid_tid} (snid, tid, status, timestamp, source) VALUES (%d, %d, %d, %d, '%s')", $subscription->snid, $tid, SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED, time(), $source); } // Execute simplenews subscribe trigger. simplenews_call_actions('subscribe', $subscription); } return $subscription; } /** * 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 confirm unsubscribe * 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 * @param string $source * Indication for the unsubscribe source. Simplenews uses these sources: * website: via any website form (with or without confirmation email) * mass subscribe: mass admin UI * mass unsubscribe: mass admin UI * action: Drupal actions */ function simplenews_unsubscribe_user($mail, $tid, $confirm = TRUE, $source = 'unknown') { $account = (object) array('mail' => $mail); $subscription = simplenews_get_subscription($account); // The unlikely case that a user is unsubscribed 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) { module_load_include('inc', 'simplenews', 'includes/simplenews.mail'); // Send confirmation email to user to confirm unsubscribe // 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['context']['newsletter'] = $newsletter; $params['context']['account'] = $subscription; drupal_mail('simplenews', 'unsubscribe', $mail, $subscription->language, $params, $params['from']['address']); } elseif (isset($subscription->tids[$tid])) { // Unsubscribe the user from the newsletter. db_query(" UPDATE {simplenews_snid_tid} SET status = %d, timestamp = %d, source = '%s' WHERE snid = %d AND tid = %d", SIMPLENEWS_SUBSCRIPTION_STATUS_UNSUBSCRIBED, time(), $source, $subscription->snid, $tid); // 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 */ //@TODO only return active subscriptions. function simplenews_user_is_subscribed($mail, $tid, $reset = FALSE) { static $subscribed = array(); if ($reset) { $subscribed = array(); } 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 AND t.status = %d", $mail, $tid, SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED) ) ? 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 tid's of active subscriptions * newsletter_subscriptions : array of newsletter subscription objects * uid : user id. 0 if account is anonymous user * mail : user email address. empty if email is unknown * name : always empty. Added for compatibility with user account object * language : language object. User preferred or default language * ) */ function simplenews_get_subscription($account) { // Load subscription data based on available account information // 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.*, u.name FROM {simplenews_subscriptions} s LEFT 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.*, u.name FROM {simplenews_subscriptions} s LEFT JOIN {users} u ON u.uid = s.uid WHERE LOWER(s.mail) = LOWER('%s')", $account->mail)); } elseif (isset($account->uid) && $account->uid > 0) { $subscription = db_fetch_object(db_query(" SELECT s.*, u.name FROM {simplenews_subscriptions} s LEFT JOIN {users} u ON u.uid = s.uid WHERE s.uid = %d", $account->uid)); } if (!empty($subscription)) { $result = db_query(" SELECT tid, status, timestamp, source FROM {simplenews_snid_tid} t WHERE t.snid = %d", $subscription->snid); $subscription->tids = array(); while ($newsletter_subscription = db_fetch_object($result)) { if ($newsletter_subscription->status == SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED) { $subscription->tids[$newsletter_subscription->tid] = $newsletter_subscription->tid; } $subscription->newsletter_subscription[$newsletter_subscription->tid] = $newsletter_subscription; } // simplenews_subscription matches account language if registered. $subscription->language = user_preferred_language($subscription); } 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(); $subscription->newsletter_subscription = 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); } /** * 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, n.created 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; } /** * 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 sent * [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) { module_load_include('inc', 'simplenews', 'includes/simplenews.mail'); $context = $params['context']; $langcode = $message['language']->language; switch ($key) { case 'node': case 'test': // Message header, body and mail headers are buffered to increase // performance when sending multiple mails. Buffered data only contains // general data, no recipient specific content. Tokens 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 retrieved 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; if (module_exists('translation')) { // If the node has translations and a translation is required // the equivalent of the node in the required language 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); } } // Check if this node-language pair has been buffered. // If not, build the message and store it for later use. if (!isset($messages[$nid][$langcode])) { $node = drupal_clone($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 $subject = '[[simplenews-newsletters-name]] [title-raw]'; if ($tid = $node->simplenews['tid']) { $term = taxonomy_get_term($tid); // Translate the newsletter term name if simplenews vocabulary uses Localized terms. $name = _simplenews_tt_newsletter_name($term, $langcode); $subject = variable_get('simplenews_email_subject_'. $term->tid, $subject); } else { $name = t('Unassigned newsletter'); } //$subject = theme('simplenews_newsletter_subject', $name, $node->title, $message['language']); $subject = token_replace($subject, 'simplenews', $context); $subject = token_replace($subject, 'node', $context['node']); $subject = str_replace(array("\r", "\n"), '', $subject); $message['subject'] = $messages[$nid][$langcode]['subject'] = $subject; // Set the active language to the node's language. // This needs to be done as otherwise the language used to send the mail // is the language of the user logged in. if (module_exists('i18n')) { i18n_selection_mode('node', $node->language); } // Build message body // Processing node body mimics node_view() with full node view $node->build_mode = 'email_'. $node->simplenews['s_format']; $node = node_build_content($node, FALSE, TRUE); $content = drupal_render($node->content); $node->body = $content; unset($node->teaser); // Set a flag to prevent token replacement during node alter. $node->simplenews_mail = TRUE; node_invoke_nodeapi($node, 'alter', FALSE, TRUE); unset($node->simplenews_mail); $body = theme(array('simplenews_newsletter_body__' . $context['node']->simplenews['tid'], 'simplenews_newsletter_body'), $node, $message['language']); // Buffer body text node and language specific $messages[$nid][$langcode]['body'] = $body; if (variable_get('simplenews_opt_inout_' . $tid, 'double') != 'hidden') { // TODO: Unsubscribe links are broken if key=='test' && $context['snid']==0 // We might pass snid / context to theme functions. // Build and buffer message footer $footer = theme(array('simplenews_newsletter_footer__' . $context['node']->simplenews['tid'], 'simplenews_newsletter_footer'), $context, $key, $message['language']); $messages[$nid][$langcode]['footer'] = $footer; } // Reset the language to the original settings. if (module_exists('i18n')) { i18n_selection_mode('reset'); } } else { // Get message data from buffer $message['headers'] = $messages[$nid][$langcode]['headers']; $message['subject'] = $messages[$nid][$langcode]['subject']; $body = $messages[$nid][$langcode]['body']; $footer = $messages[$nid][$langcode]['footer']; } // Build message body, replace tokens. $body = token_replace($body, 'simplenews', $context); // Convert to plain text if required. if ($context['node']->simplenews['s_format'] == 'plain') { $body = simplenews_html_to_text($body, variable_get('simplenews_hyperlinks_' . $context['node']->simplenews['tid'], 1)); } $message['body']['body'] = $body; // Build message footer, replace tokens. $footer = token_replace($footer, 'simplenews', $context); $message['body']['footer'] = $footer; // Add user specific header data. $message ['headers']['List-Unsubscribe'] = '<' . token_replace('[simplenews-unsubscribe-url]', 'simplenews', $context) . '>'; break; case 'subscribe': // Use formatted from address "name" $message['headers']['From'] = $params['from']['formatted']; $message['subject'] = _simplenews_subscription_confirmation_text('subscribe_subject', $langcode); $message['subject'] = token_replace($message['subject'], 'simplenews_subscription', $context); if (simplenews_user_is_subscribed($context['account']->mail, $context['newsletter']->tid)) { $message['body'] = _simplenews_subscription_confirmation_text('subscribe_subscribed', $langcode); $message['body'] = token_replace($message['body'], 'simplenews_subscription', $context); } else { $message['body'] = _simplenews_subscription_confirmation_text('subscribe_unsubscribed', $langcode); $message['body'] = token_replace($message['body'], 'simplenews_subscription', $context); } break; case 'unsubscribe': // Use formatted from address "name" $message['headers']['From'] = $params['from']['formatted']; $message['subject'] = _simplenews_subscription_confirmation_text('subscribe_subject', $langcode); $message['subject'] = token_replace($message['subject'], 'simplenews_subscription', $context); if (simplenews_user_is_subscribed($context['account']->mail, $context['newsletter']->tid)) { $message['body'] = _simplenews_subscription_confirmation_text('unsubscribe_subscribed', $langcode); $message['body'] = token_replace($message['body'], 'simplenews_subscription', $context); } else { $message['body'] = _simplenews_subscription_confirmation_text('unsubscribe_unsubscribed', $langcode); $message['body'] = token_replace($message['body'], 'simplenews_subscription', $context); } break; } // Debug message to check for outgoing emails messages. // Debug message of node and test emails is set in simplenews_mail_mail(). if (variable_get('simplenews_debug', FALSE) && $key != 'node' && $key != 'test') { watchdog('simplenews', 'Outgoing email. Message type: %type
Subject: %subject
Recipient: %to', array( '%type' => $key, '%to' => $message['to'], '%subject' => $message['subject'] ), WATCHDOG_DEBUG); } } /** * Implementation of hook_views_api(). */ function simplenews_views_api() { return array( 'api' => 2, 'path' => drupal_get_path('module', 'simplenews') . '/includes/views', ); } /** * 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); } } /** * Get array of newsletters with names translated. * * If required newsletter names are translated based on the global language. * Hidden newsletters (opt-in/out setting is 'hidden') are not included. * @param int $vid * Newsletter vocabulary ID * @param boolean $show_all * On false hidden newsletters will not be returned. * On true all newsletter will be returned. * @return array of newsletters objects. */ function simplenews_get_newsletters($vid, $show_all = FALSE, $reset = FALSE) { static $newsletters = NULL; if (is_array($newsletters) && !$reset) { return $newsletters; } $newsletters = array(); foreach (taxonomy_get_tree($vid) as $term) { if (variable_get('simplenews_opt_inout_' . $term->tid, 'double') != 'hidden' || $show_all) { $newsletter = new stdClass(); $newsletter->tid = $term->tid; $newsletter->name = _simplenews_tt_newsletter_name($term); $newsletters[$term->tid] = $newsletter; } } return $newsletters; } /** * Implementation of hook_token_list(). */ function simplenews_token_list($type = 'all') { $tokens = array(); switch ($type) { case 'simplenews_subscription': $tokens['simplenews']['simplenews-subscribe-url'] = t('URL of the subscribe confirmation page'); $tokens['simplenews']['simplenews-unsubscribe-url'] = t('URL of the unsubscribe confirmation page'); $tokens['simplenews']['simplenews-receiver-mail'] = t('Email address of the newsletter receiver'); $tokens['simplenews']['simplenews-from-name'] = t('From name'); $tokens['simplenews']['simplenews-from-mail'] = t('From email address'); $tokens['simplenews']['simplenews-newsletters-name'] = t('The name of the newsletter series'); $tokens['simplenews']['simplenews-newsletters-url'] = t('URL of the taxonomy page listing the issues of this newsletter series'); $tokens['simplenews']['simplenews-subscriptions-url'] = t('URL of the manage subscriptions page'); break; case 'all': case 'simplenews': $tokens['simplenews']['simplenews-subscribe-url'] = t('URL of the subscribe confirmation page.'); $tokens['simplenews']['simplenews-unsubscribe-url'] = t('URL of the unsubscribe confirmation page'); $tokens['simplenews']['simplenews-receiver-name'] = t('Username of the newsletter receiver or anonymous user name.'); $tokens['simplenews']['simplenews-receiver-mail'] = t('Email address of the newsletter receiver'); $tokens['simplenews']['simplenews-from-name'] = t('From name'); $tokens['simplenews']['simplenews-from-mail'] = t('Email address from which the newsletter is sent'); $tokens['simplenews']['simplenews-newsletter-url'] = t('URL of this newsletter issue'); $tokens['simplenews']['simplenews-newsletters-name'] = t('The name of the newsletter series'); $tokens['simplenews']['simplenews-newsletters-url'] = t('URL of the taxonomy page listing the issues of this newsletter series'); $tokens['simplenews']['simplenews-subscriptions-url'] = t('URL of the manage subscriptions page'); break; } return $tokens; } /** * Implementation of hook_token_value(). */ function simplenews_token_values($type, $object = NULL, $options = array()) { $values = array(); switch ($type) { case 'all': case 'simplenews': $account = $object['account']; $node = $object['node']; $language = isset($account->language) ? $account->language : language_default(); $langcode = $language->language; $urlargs = array('absolute' => TRUE, 'language' => $language); // Build tokens for 'simplenews' only. $values['simplenews-receiver-name'] = !empty($account->name) ? check_plain($account->name) : check_plain(variable_get('anonymous', 'Anonymous')); $values['simplenews-newsletter-url'] = url('node/' . $node->nid, $urlargs); // Try to switch to translation if possible. if ($node->tnid) { $translations = translation_node_get_translations($node->tnid); $node_translated = $translations[$langcode]; if ($node_translated) { $values['simplenews-newsletter-url'] = url('node/' . $node_translated->nid, $urlargs); } } // Intentionally fall through (no break). case 'simplenews_subscription': $account = $object['account']; $newsletter = $object['newsletter']; $node = $object['node']; $language = isset($account->language) ? $account->language : language_default(); $urlargs = array('absolute' => TRUE, 'language' => $language); // Build hash for (un)subscribe URL. $hash = ''; if (isset($account->snid) && isset($newsletter->tid)) { $hash = _simplenews_generate_hash($account->mail, $account->snid, $newsletter->tid); } // When simplenews_token_values() is called from simplenews_nodeapi() // $newsletter->name contains no value. Newsletter name is // reconstructed from $node->simplenews['tid']. if (!isset($newsletter->name) || !isset($newsletter->tid)) { $tid = isset($newsletter->tid) ? $newsletter->tid : $node->simplenews['tid']; if ($tid && ($term = taxonomy_get_term($tid))) { $newsletter->name = $term->name; $newsletter->tid = $tid; } } module_load_include('inc', 'simplenews', 'includes/simplenews.mail'); // Translate newsletter name $newsletter_name = _simplenews_tt_newsletter_name($newsletter, $language->language); // Info for simplenews-from-name and simplenews-from-mail tokens $from = _simplenews_set_from($node); // Build tokens for both 'simplenews_subscription' and 'simplenews'. $values['simplenews-subscribe-url'] = url('newsletter/confirm/add/' . $hash, $urlargs); $values['simplenews-unsubscribe-url'] = url('newsletter/confirm/remove/' . $hash, $urlargs); $values['simplenews-receiver-mail'] = $account->mail; $values['simplenews-from-name'] = $from['formatted']; $values['simplenews-from-mail'] = $from['address']; $values['simplenews-newsletters-name'] = $newsletter_name ? check_plain($newsletter_name) : ''; $values['simplenews-newsletters-url'] = ''; if (isset($newsletter->tid)) { $values['simplenews-newsletters-url'] = url('taxonomy/term/' . $newsletter->tid, $urlargs); } $values['simplenews-subscriptions-url'] = url('newsletter/subscriptions', $urlargs); break; } return $values; } /** * 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. Newsletter issues are grouped by a newsletter 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 balance the mailserver load.') . "

\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 when they (un)subscribe. 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 '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 or HTML Mail to send HTML emails or emails with attachments (both plain text and HTML).', array( '!mime_mail_url' => 'http://drupal.org/project/mimemail', '!html_mail_url' => 'http://drupal.org/project/htmlmail' )) . "
  • \n"; } $help .= "
"; return $help; case 'admin/settings/simplenews/subscription': if (variable_get('language_count', 1) > 1) { if (module_exists('i18nstrings')) { global $language; $language_default = variable_get('language_default', $language); $help = '

' . t('This is a Multilingual website. Enter text for confirmation subject and body in the default site language (@language).', array( '@language' => $language_default->name )) . "

\n"; } else { $help = '

' . t('This is a Multilingual website. Enable the String translation module to enable translation of the confirmation subject and body.', array( '@url' => url('admin/build/modules') )) . "

\n"; } return $help; } break; 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; case 'admin/content/node-type/simplenews/display/simplenews': $help = '

' . t("'Plain' display settings apply to the content of emails sent in plain text format. 'HTML' display settings apply to both HTML and plain text alternative content of emails sent in HTML format.") . "

\n"; return $help; } // Cover node add simplenews content types. if ($arg[0]=='node' && $arg[1]=='add') { $type = str_replace('-', '_', $arg[2]); if (in_array($type, variable_get('simplenews_content_types', array('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; } } } /** * Implementation of hook_locale(). */ function simplenews_locale($op = 'groups', $group = NULL) { switch ($op) { case 'groups': return array('simplenews' => t('Simplenews')); break; case 'info': $info['simplenews']['refresh callback'] = 'simplenews_locale_refresh'; return $info; break; } } /** * Refresh translatable strings. * * @see _simplenews_subscription_confirmation_text() */ function simplenews_locale_refresh() { $keys = array( 'subscribe_unsubscribed', 'subscribe_subscribed', 'unsubscribe_subscribed', 'unsubscribe_unsubscribed', 'subscribe_subject', ); foreach ($keys as $key) { i18nstrings_update('simplenews:' . $key, _simplenews_subscription_confirmation_text($key, NULL, FALSE)); } return TRUE; } /** * Generate default and custom subscription confirmation email text. * * @param string $key * Text identification key * @param object $langcode * Language code * @param boolean $translate * FALSE: force return value to be untranslated text. * @return * Invitation text. Optionally translated. * * @see simplenews_locale() */ function _simplenews_subscription_confirmation_text($key, $language = NULL, $translate = TRUE) { $langcode = isset($language) ? $language->language : NULL; $text = variable_get('simplenews_confirm_'. $key, FALSE); // If administrator did not change the text, the variable is empty. // We get the default here. if (!$text) { $args = array(); switch ($key) { case 'subscribe_unsubscribed': $text = t("We have received a request to subscribe [simplenews-receiver-mail] to the [simplenews-newsletters-name] newsletter on [site-name] website at [site-url]. To confirm this subscription please use the link below.\n\n[simplenews-subscribe-url]", $args, $langcode); break; case 'subscribe_subscribed': $text = t("We have received a request to subscribe [simplenews-receiver-mail] to the [simplenews-newsletters-name] newsletter on [site-name] website at [site-url]. However, this email is already subscribed to this newsletter. If you intended to unsubscribe please visit our site at:\n[site-url]", $args, $langcode); break; case 'unsubscribe_subscribed': $text = t("We have received a request to unsubscribe [simplenews-receiver-mail] from the [simplenews-newsletters-name] on [site-name] website at [site-url]. To confirm this cancellation please use the link below.\n\n[simplenews-unsubscribe-url]", $args, $langcode); break; case 'unsubscribe_unsubscribed': $text = t("We have received a request to unsubscribe [simplenews-receiver-mail] from the [simplenews-newsletters-name] on [site-name] website at [site-url]. However, this email is not subscribed to this newsletter. If you intended to subscribe please visit our site at:\n[site-url]", $args, $langcode); break; case 'subscribe_subject': $text = t("Confirmation for [simplenews-newsletters-name] from [site-name]", $args, $langcode); break; } } // If this is a multilingual website we use i18nstrings module to translate the content. if (variable_get('language_count', 1) > 1 && function_exists('i18nstrings') && $translate) { $text = i18nstrings('simplenews:' . $key, $text, $langcode); } return $text; } /** * Helper function to translate a newsletter name if required. * * @param $newsletter * Newsletter object. Typically from taxonomy_get_term(). * $newsletter -> tid newsletter tid * $newsletter -> name newsletter name * @param $langcode * Optional language code (defaults to current global $language); * * @return translated newsletter name. */ function _simplenews_tt_newsletter_name($newsletter, $langcode = NULL) { global $language; $langcode = isset($langcode) ? $langcode : $language->language; if (module_exists('i18ntaxonomy') && i18ntaxonomy_vocabulary(variable_get('simplenews_vid', '')) == I18N_TAXONOMY_LOCALIZE) { return tt('taxonomy:term:' . $newsletter->tid . ':name', $newsletter->name, $langcode); } return $newsletter->name; } /** * Flatten a nested array */ function _simplenews_flatten_array($array) { $return = array(); foreach ($array as $key => $value) { if (is_array($value)) { $return += _simplenews_flatten_array($value); } else { $return[$key] = $value; } } return $return; } /** * 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. * * Mime Mail or HTML Mail module must be installed to send HTML mails. */ function _simplenews_format_options() { $options = array('plain' => t('plain')); if (module_exists('mimemail') || module_exists('htmlmail')) { $options['html'] = t('html'); } return $options; } /** * Get defaults for the simplenews node form. */ function _simplenews_get_node_defaults() { $defaults = array( 'advanced' => array( 's_format' => variable_get('simplenews_format', 'plain'), 'priority' => variable_get('simplenews_priority', SIMPLENEWS_PRIORITY_NONE), 'receipt' => variable_get('simplenews_receipt', 0), ), 's_status' => '0', 'test_address' => variable_get('simplenews_test_address', variable_get('site_mail', ini_get('sendmail_from'))), ); return $defaults; } /** * Implementation of hook_content_build_modes(). */ function simplenews_content_build_modes() { return array( 'simplenews' => array( 'title' => t('Simplenews'), 'build modes' => array( 'email_plain' => array( 'title' => t('Email: Plain'), 'views style' => FALSE, ), 'email_html' => array( 'title' => t('Email: HTML'), 'views style' => FALSE, ), ), ), ); } /** * Simplenews email verification * * Wrapper for supporting community modules */ function simplenews_valid_email_address($email = '') { if (module_exists('email_verify')) { //Same validation as in email_verify.module on line 33 return module_invoke('email_verify', 'check', $email); } return valid_email_address($email); } /** * Implementation of hook_theme(). */ function simplenews_theme() { $path = drupal_get_path('module', 'simplenews'); return array( 'simplenews_multi_block' => array( 'template' => 'simplenews-multi-block', 'arguments' => array(), 'path' => $path . '/theme', ), 'simplenews_block' => array( 'template' => 'simplenews-block', 'path' => $path . '/theme', 'arguments' => array('tid' => NULL), 'pattern' => 'simplenews_block__', ), 'simplenews_status' => array( 'template' => 'simplenews-status', 'file' => 'includes/simplenews.admin.inc', 'path' => $path . '/theme', 'arguments' => array('status' => NULL, 'source' => NULL, 'already_sent' => NULL, 'sent_subscriber_count' => NULL), ), 'simplenews_newsletter_subject' => array( 'arguments' => array('name' => NULL, 'title' => NULL, 'language' => NULL), 'path' => $path . '/theme', ), 'simplenews_newsletter_body' => array( 'template' => 'simplenews-newsletter-body', 'arguments' => array('node' => NULL, 'language' => NULL), 'pattern' => 'simplenews_newsletter_body__', 'path' => $path . '/theme', ), 'simplenews_newsletter_footer' => array( 'template' => 'simplenews-newsletter-footer', 'arguments' => array('context' => NULL, 'key' => NULL, 'language' => NULL), 'pattern' => 'simplenews_newsletter_footer__', 'path' => $path . '/theme', ), 'simplenews_subscription_list' => array( 'file' => 'includes/simplenews.admin.inc', 'arguments' => array('form' => NULL), 'path' => $path . '/theme', ), ); } /** * Process variables to format the simplenews block. * * Collect data and apply access restrictions. * * $variables * * @see simplenews-block.tpl.php */ 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 // @todo: clean localization / i18n needed $variables['message'] = check_plain(variable_get('simplenews_block_m_' . $tid, t('Stay informed on our latest news!'))); if (user_access('subscribe to newsletters')) { module_load_include('inc', 'simplenews', 'includes/simplenews.subscription'); $variables['form'] = drupal_get_form('simplenews_block_form_' . $tid); $variables['subscription_link'] = l(t('Manage my subscriptions'), 'newsletter/subscriptions'); } $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); } /** * Process variables to format the simplenews newsletter footer. * * $variables are empty: * * @see simplenews-multi-block.tpl.php */ function template_preprocess_simplenews_multi_block(&$variables) { global $user; // Block content variables $variables['message'] = check_plain(variable_get('simplenews_block_m_multiple', t('Select the newsletter(s) to which you want to subscribe or unsubscribe.'))); $variables['form'] = drupal_get_form('simplenews_subscriptions_multi_block_form'); // Additional variables $variables['subscribed'] = empty($user->uid) ? FALSE : (simplenews_user_is_subscribed($user->mail, $tid) == TRUE); $variables['user'] = !empty($user->uid); } /** * Theme the newsletter email subject. */ function theme_simplenews_newsletter_subject($name, $title, $language) { return '[' . $name . '] ' . $title; } /** * Process variables to format the simplenews newsletter body. * * $variables contains: * - $node * - $language * * @see simplenews-newsletter-body.tpl.php */ function template_preprocess_simplenews_newsletter_body(&$variables) { $variables['title'] = check_plain($variables['node']->title); $variables['body'] = $variables['node']->body; } /** * Process variables to format the simplenews newsletter footer. * * $variables contains: * - $node: newsletter node object * - $language: language object * - $key: email key [node|test] * * @see simplenews-newsletter-footer.tpl.php */ function template_preprocess_simplenews_newsletter_footer(&$variables) { $variables['format'] = $variables['context']['node']->simplenews['s_format']; $variables['unsubscribe_text'] = t('Unsubscribe from this newsletter', array(), $variables['language']->language); $variables['test_message'] = t('This is a test version of the newsletter.', array(), $variables['language']->language); } /** * Implements hook_cronapi(). * * As initiated by elysia_cron. * http://drupal.org/project/elysia_cron **/ function simplenews_cronapi($op) { switch ($op) { case 'list': return array( 'simplenews_cron' => t('Process simplenews mail spool'), ); case 'rule': return '5 * * * *'; case 'execute': break; } }