'Newsletters', 'description' => 'Manage newsletters, subscribers, and settings.', 'access arguments' => array('administer newsletters'), 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_stats'), 'file' => 'includes/newsletter.admin.inc', ); $items['admin/config/media/newsletter/stats'] = array( 'title' => 'Statistics', 'access arguments' => array('access newsletter statistics'), 'type' => MENU_DEFAULT_LOCAL_TASK, ); $items['admin/config/media/newsletter/stats/general'] = array( 'title' => 'General', 'description' => 'Watch general statistics.', 'access arguments' => array('access newsletter statistics'), 'type' => MENU_DEFAULT_LOCAL_TASK, ); $items['admin/config/media/newsletter/stats/graphic'] = array( 'title' => 'Graphic', 'description' => 'Watch advanced JQuery statistics.', 'access arguments' => array('access newsletter statistics'), 'type' => MENU_LOCAL_TASK, 'page callback' => 'newsletter_stats_graphic', 'file' => 'includes/newsletter.admin.inc', 'weight' => 1, ); $items['admin/config/media/newsletter/create-send'] = array( 'title' => 'Create/Send', 'description' => 'Create custom static newsletters and send non-automated ones', 'access arguments' => array('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'page callback' => 'newsletter_draft_manual_list', 'file' => 'includes/newsletter.admin.inc', 'weight' => 1, ); $items['admin/config/media/newsletter/create-send/draft/%newsletter_newsletter'] = array( 'title' => 'Send a newsletter draft', 'access arguments' => array('administer newsletters'), 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_form_send_draft', 6), 'file' => 'includes/newsletter.admin.inc', ); $items['admin/config/media/newsletter/create-send/draft/delete/%newsletter_newsletter'] = array( 'title' => 'Delete a newsletter draft', 'access arguments' => array('administer newsletters'), 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_form_delete_draft', 7), 'file' => 'includes/newsletter.admin.inc', ); $items['admin/config/media/newsletter/create-send/newsletter/delete/%newsletter_newsletter'] = array( 'title' => 'Delete a newsletter draft', 'access arguments' => array('administer newsletters'), 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_form_delete_newsletter', 7), 'file' => 'includes/newsletter.admin.inc', ); $items['admin/config/media/newsletter/create-send/new'] = array( 'title' => 'Create and send a custom newsletter', 'description' => 'Create a custom static newsletter', 'access arguments' => array('administer newsletters'), 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_create_send'), 'file' => 'includes/newsletter.admin.inc', 'type' => MENU_LOCAL_ACTION, ); $items['admin/config/media/newsletter/create-send/send/%newsletter_list'] = array( 'title' => 'Send a manual newsletter', 'access arguments' => array('administer newsletters'), 'page callback' => 'newsletter_manual_send', 'page arguments' => array(6), 'file' => 'includes/newsletter.admin.inc', 'type' => MENU_CALLBACK, ); $items['admin/config/media/newsletter/lists'] = array( 'title' => 'Lists', 'description' => 'Find and manage newsletter lists.', 'access arguments' => array('administer newsletters'), 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_list'), 'file' => 'includes/newsletter.admin.inc', 'type' => MENU_LOCAL_TASK, 'weight' => 2, ); $items['admin/config/media/newsletter/subscribers'] = array( 'title' => 'Subscribers', 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_subscriber_list'), 'description' => 'List subscribers.', 'access arguments' => array('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'file' => 'includes/newsletter.admin.inc', 'weight' => 3, ); $items['admin/config/media/newsletter/lists/add'] = array( 'title' => 'Add new list', 'page callback' => 'newsletter_list_add', 'description' => 'Add new newsletter list.', 'access arguments' => array('administer newsletters'), 'type' => MENU_LOCAL_ACTION, 'file' => 'includes/newsletter.admin.inc', ); $items['admin/config/media/newsletter/subscribers/add'] = array( 'title' => 'Add new subscriber', 'page callback' => 'newsletter_subscriber_add', 'description' => 'Add new list subscriber.', 'access arguments' => array('administer newsletters'), 'type' => MENU_LOCAL_ACTION, 'file' => 'includes/newsletter.admin.inc', ); $items['admin/config/media/newsletter/subscribers/add-mass'] = array( 'title' => 'Add subscribers (Mass)', 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_subscriber_add_mass'), 'description' => 'Add subscribers.', 'access arguments' => array('administer newsletters'), 'type' => MENU_LOCAL_ACTION, 'file' => 'includes/newsletter.admin.inc', ); $items['admin/config/media/newsletter/lists/delete/%newsletter_list'] = array( 'title' => 'Delete newsletter list', 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_list_delete', 6), 'access arguments' => array('administer newsletters'), 'type' => MENU_CALLBACK, 'file' => 'includes/newsletter.admin.inc', ); $items['admin/config/media/newsletter/lists/edit/%newsletter_list'] = array( 'title' => 'Edit newsletter list', 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_list_edit', 6), 'access arguments' => array('administer newsletters'), 'file' => 'includes/newsletter.admin.inc', 'type' => MENU_CALLBACK, ); $items['admin/config/media/newsletter/subscribers/edit/%newsletter_subscriber'] = array( 'title' => 'Edit newsletter subscriber', 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_subscriber_edit', 6), 'access arguments' => array('administer newsletters'), 'file' => 'includes/newsletter.admin.inc', 'type' => MENU_CALLBACK, ); $items['admin/config/media/newsletter/subscribers/delete/%newsletter_subscriber'] = array( 'title' => 'Delete subscriber', 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_subscriber_delete', 6), 'access arguments' => array('administer newsletters'), 'file' => 'includes/newsletter.admin.inc', 'type' => MENU_CALLBACK, ); $items['admin/config/media/newsletter/templates'] = array( 'title' => 'Templates', 'description' => 'Administer newsletter templates.', 'access arguments' => array('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_template_list'), 'file' => 'includes/newsletter.admin.inc', 'weight' => 4, ); $items['admin/config/media/newsletter/templates/mail'] = array( 'title' => 'Mail templates', 'description' => 'Administer mail templates.', 'access arguments' => array('administer newsletters'), 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10, ); $items['admin/config/media/newsletter/templates/mail/add'] = array( 'title' => 'Add new mail template', 'description' => 'Administer mail templates.', 'access arguments' => array('administer newsletters'), 'type' => MENU_LOCAL_ACTION, 'page callback' => 'newsletter_template_add', 'file' => 'includes/newsletter.admin.inc', ); $items['admin/config/media/newsletter/templates/delete/%newsletter_template'] = array( 'title' => 'Delete newsletter templates', 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_template_delete', 6), 'access arguments' => array('administer newsletters'), 'file' => 'includes/newsletter.admin.inc', 'type' => MENU_CALLBACK, ); $items['admin/config/media/newsletter/templates/edit/%newsletter_template'] = array( 'title' => 'Edit newsletter templates', 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_template_edit', 6), 'access arguments' => array('administer newsletters'), 'file' => 'includes/newsletter.admin.inc', 'type' => MENU_CALLBACK, ); $items['admin/config/media/newsletter/templates/confirmation'] = array( 'title' => 'Confirmation', 'description' => 'Edit confirmation template.', 'page callback' => 'newsletter_basic_template_edit', 'page arguments' => array('1'), 'access arguments' => array('administer newsletters'), 'file' => 'includes/newsletter.admin.inc', 'type' => MENU_LOCAL_TASK, 'weight' => -9, ); $items['admin/config/media/newsletter/templates/welcome'] = array( 'title' => 'Welcome', 'description' => 'Edit welcome template.', 'page callback' => 'newsletter_basic_template_edit', 'page arguments' => array('2'), 'access arguments' => array('administer newsletters'), 'file' => 'includes/newsletter.admin.inc', 'type' => MENU_LOCAL_TASK, 'weight' => -8, ); $items['admin/config/media/newsletter/templates/unsubscribe'] = array( 'title' => 'Unsubscribe', 'description' => 'Edit unsubscribe template.', 'page callback' => 'newsletter_basic_template_edit', 'page arguments' => array('3'), 'access arguments' => array('administer newsletters'), 'file' => 'includes/newsletter.admin.inc', 'type' => MENU_LOCAL_TASK, 'weight' => -7, ); $items['admin/config/media/newsletter/configure'] = array( 'title' => 'Settings', 'description' => 'Configure newsletter lists.', 'access arguments' => array('administer newsletters'), 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_configure'), 'file' => 'includes/newsletter.admin.inc', 'weight' => 5, ); $items['newsletter/subscribe'] = array( 'title' => 'Subscribe', 'description' => 'Subscribe to our newsletters.', 'access arguments' => array('subscribe newsletters'), 'page arguments' => array('newsletter_manage_subscriptions_form'), 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'file' => 'includes/newsletter.pages.inc', ); $items['newsletter/confirm/%newsletter_subscriber_by_hash'] = array( 'title' => 'Confirm subscription', 'description' => 'Confirm your subscription to our newsletters.', 'access arguments' => array('subscribe newsletters'), 'type' => MENU_CALLBACK, 'page callback' => 'newsletter_confirm', 'page arguments' => array(2), 'file' => 'includes/newsletter.pages.inc', ); $items['newsletter/unsubscribe/%newsletter_subscriber_by_hash'] = array( 'title' => 'Unsubscribe', 'description' => 'Confirm that you want to unsubscribe from our newsletters.', 'access arguments' => array('subscribe newsletters'), 'type' => MENU_CALLBACK, 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_unsubscribe', 2), 'file' => 'includes/newsletter.pages.inc', ); $items['newsletter/statistics/%newsletter_subscriber_by_hash'] = array( 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, 'page callback' => 'newsletter_statistics_open', 'page arguments' => array(2), 'file' => 'includes/newsletter.pages.inc', ); $items['newsletter/edit/%newsletter_subscriber_by_hash'] = array( 'title' => 'Edit newsletter subscriptions', 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_manage_subscriptions_form', 2), 'access callback' => TRUE, 'type' => MENU_LOCAL_TASK, 'file' => 'includes/newsletter.pages.inc', ); $items['user/%user/newsletter'] = array( 'title' => 'Newsletter subscriptions', 'page callback' => 'drupal_get_form', 'page arguments' => array('newsletter_manage_subscriptions_form', 1), 'access callback' => 'newsletter_edit_subsdcriber_access', 'access arguments' => array(1), 'type' => MENU_LOCAL_TASK, 'file' => 'includes/newsletter.pages.inc', ); return $items; } /** * Implements hook_permission(). */ function newsletter_permission() { $permissions = array(); $permissions['administer newsletters'] = array( 'title' => t('Administer newsletters'), 'description' => t('Access the newsletter administration pages.'), ); $permissions['subscribe newsletters'] = array( 'title' => t('Subscribe newsletters'), 'description' => t('Can subscribe to various newsletter lists.'), ); $permissions['access newsletter statistics'] = array( 'title' => t('Access newsletter statistics'), 'description' => t('Access the newsletter statistics pages.'), ); return $permissions; } /** * Implements hook_cron(). */ function newsletter_cron() { $status = array(); $nlids_sent = array(); // Custom Newsletters $custom_queues = variable_get('newsletter_custom_for_next_cron', array()); if (!empty($custom_queues)) { foreach ($custom_queues as $num => $custom_queue) { $data = newsletter_create($custom_queue['subscribers'], $custom_queue['ntid'], $custom_queue['nnid']) ->send(); $status = array_merge($status, $data['status']); $subscribers_left = $data['subscribers_left']; if (!empty($subscribers_left)) { $custom_queues[$num]['subscribers'] = $subscribers_left; } else { unset($custom_queues[$num]); } } variable_set('newsletter_custom_for_next_cron', $custom_queues); } // Nesletters with remaining subscribers or Manual queued $remaining = variable_get('newsletter_for_next_cron', array()); if (!empty($remaining)) { foreach ($remaining as $nlid => $data) { if ($data === TRUE) { // There is a new Manual newsletter in the queue $remaining[$nlid] = array(); variable_set('newsletter_for_next_cron', $remaining); $result = newsletter_create($nlid)->send(); $status = array_merge($status, $result); $nlids_sent[] = $nlid; } elseif (!empty($data)) { // There are remaining subscribers in one already sent newsletter $result = newsletter_create($nlid)->send(); $status = array_merge($status, $result); $nlids_sent[] = $nlid; } } } // Automated Newsletter lists that didn't have remaining for this cron run $cron_lists = db_query("SELECT nlid FROM {newsletter_list} WHERE (send_again = CURDATE() OR send_again IS NULL) AND (send_rate = 'Daily' OR send_rate = 'Weekly' OR send_rate = 'Monthly')") ->fetchAll(); if (is_array($cron_lists)) { foreach ($cron_lists as $cron_list) { if (!in_array($cron_list->nlid, $nlids_sent, TRUE)) { $result = newsletter_create($cron_list->nlid)->send(); $status = array_merge($status, $result); } } } newsletter_feedback($status); } /** * Implements hook_node_insert(). */ function newsletter_node_insert($node) { $status = array(); $custom_send_rate_lists = newsletter_custom_send_rate_lists(); foreach ($custom_send_rate_lists as $list) { $newsletter = newsletter_create($list->nlid); if ($newsletter->checkCustom()) { $status = array_merge($status, $newsletter->send()); } } newsletter_feedback($status); } /** * Implements hook_user_insert(). */ function newsletter_user_insert(&$edit, $account, $category) { if ($lists = variable_get('newsletter_auto_subscribe_new_users', array())) { $subscriber = new stdClass(); $subscriber->email = $account->mail; $subscriber->uid = $account->uid; foreach ($lists as $list) { $subscriber->field_newsletter_list[LANGUAGE_NONE][]['target_id'] = $list; } entity_get_controller('newsletter_subscriber')->save($subscriber, variable_get('newsletter_send_confirm')); } } /** * Implements hook_taxonomy_vocabulary_insert(). */ function newsletter_taxonomy_vocabulary_insert($vocabulary) { // Avoid conflict with standard installation profile. // Also don't create field for the Newsletter Categories vocabulary. if (($vocabulary->machine_name == 'tags' && $vocabulary->vid == 2) || $vocabulary->machine_name == 'newsletter_categories') { return; } // Field names have 32 char limit. $field_name = 'field_' . substr($vocabulary->machine_name, 0, 26); $field = array( 'field_name' => 'field_' . $field_name, 'type' => 'taxonomy_term_reference', 'cardinality' => FIELD_CARDINALITY_UNLIMITED, 'settings' => array( 'allowed_values' => array( array( 'vocabulary' => $vocabulary->machine_name, 'parent' => 0, ), ), ), ); field_create_field($field); $instance = array( 'field_name' => 'field_' . $vocabulary->machine_name, 'entity_type' => 'newsletter_template', 'bundle' => 'newsletter_template', 'label' => $vocabulary->name, 'widget' => array( 'weight' => 0, 'type' => 'options_select', ), ); field_create_instance($instance); } /** * Implements hook_block_info(). */ function newsletter_block_info() { $blocks['newsletter_subscribe'] = array( 'info' => t('Newsletter: Subscribe'), ); return $blocks; } /** * Implements hook_block_view(). */ function newsletter_block_view($delta = '') { switch ($delta) { case 'newsletter_subscribe': if ( user_access('subscribe newsletters') && (!newsletter_is_subscribed() || variable_get('newsletter_always_show_subscribe_block', FALSE)) ) { newsletter_add_js(); module_load_include('inc', 'newsletter', 'includes/newsletter.pages'); $block['subject'] = t('Subscribe to our Newsletters'); $block['content'][] = array( '#prefix' => '
', '#markup' => check_plain(variable_get('newsletter_block_prefix')), '#suffix' => '
', ); $block['content'][] = drupal_get_form('newsletter_subscribe_form'); $block['content'][] = array( '#prefix' => '
', '#markup' => check_plain(variable_get('newsletter_block_suffix')), '#suffix' => '
', ); } else { $block = array(); } break; } return $block; } /** * Implements hook_variable_info(). */ function newsletter_variable_info($options) { $variable['newsletter_block_prefix'] = array( 'title' => t('Newsletter subscribe block prefix'), 'description' => t('This text will appear above the email address in the subscribe block.'), 'type' => 'string', 'access' => 'administer newsletters', ); $variable['newsletter_block_suffix'] = array( 'title' => t('Newsletter subscribe block suffix'), 'description' => t('This text will appear below the email address in the subscribe block.'), 'type' => 'string', 'access' => 'administer newsletters', ); return $variable; } /** * Implements hook_block_configure(). */ function newsletter_block_configure($delta = '') { $form = array(); if ($delta == 'newsletter_subscribe') { $form['newsletter_block_prefix'] = array( '#type' => 'textarea', '#title' => t('Text before email address'), '#description' => t('This text will appear above the email address in the subscribe block.'), '#default_value' => variable_get('newsletter_block_prefix'), ); $form['newsletter_block_suffix'] = array( '#type' => 'textarea', '#title' => t('Text after email address'), '#description' => t('This text will appear below the email address in the subscribe block.'), '#default_value' => variable_get('newsletter_block_suffix'), ); } return $form; } /** * Implements hook_block_save(). */ function newsletter_block_save($delta = '', $edit = array()) { if ($delta == 'newsletter_subscribe') { // Save the configuration to the database. variable_set('newsletter_block_prefix', $edit['newsletter_block_prefix']); variable_set('newsletter_block_suffix', $edit['newsletter_block_suffix']); } return; } /** * Implements hook_node_view(). */ function newsletter_node_view($node, $view_mode, $langcode) { // Only add once, since this hook may run many times in a request static $i; if (isset($_GET['source']) && $_GET['source'] == 'newsletter' && !$i) { db_query("UPDATE {newsletter_newsletter} SET clicks = clicks + 1 WHERE nnid = :id", array(':id' => $_GET['nnid'])); $i++; } } /** * Implements hook_token_info(). */ function newsletter_token_info() { $type = array( 'name' => t('Newsletter'), 'description' => t('Tokens related to newsletters.'), 'needs-data' => 'newsletter', ); $newsletter['confirmation_url'] = array( 'name' => t('Confirmation URL'), 'description' => t('The url with the generated hash where the subscriber confirms subscription'), ); $newsletter['subscription_ip'] = array( 'name' => t('Subscription IP'), 'description' => t('The url with the generated hash where the subscriber confirms subscription'), ); $newsletter['unsubscribe_url'] = array( 'name' => t('Unsubscribe URL'), 'description' => t('The URL that unsubscribes the current user from subscribed newsletters'), ); $newsletter['edit_subscription_url'] = array( 'name' => t('Edit subscription URL'), 'description' => t('The URL that allows even anonymous users to edit their newlsetter subscription'), ); $newsletter['subscriber_firstname'] = array( 'name' => t("Subscriber's First Name"), 'description' => t('You need to have this required in the personal info form, in order to use it efficiently'), ); $newsletter['subscriber_lastname'] = array( 'name' => t("Subscriber's Last Name"), 'description' => t('You need to have this required in the personal info form, in order to use it efficiently'), ); $newsletter['subscriber_email'] = array( 'name' => t("Subscriber's e-mail"), 'description' => t("Subscriber's e-mail"), ); $newsletter['subscription_time'] = array( 'name' => t('Subscription Time'), 'description' => t('The date this subscriber subscribed to your list'), ); $newsletter['list_name'] = array( 'name' => t('List name'), 'description' => t('The newsletter list name'), ); $newsletter['list_description'] = array( 'name' => t("List's description"), 'description' => t('The newsletter list description'), ); $newsletter['list_category'] = array( 'name' => t("List's category"), 'description' => t('The newsletter list category'), ); return array( 'types' => array('newsletter' => $type), 'tokens' => array('newsletter' => $newsletter), ); } /** * Implements hook_tokens(). */ function newsletter_tokens($type, $tokens, array $data = array(), array $options = array()) { $sanitize = !empty($options['sanitize']); $replacements = array(); if ($type == 'newsletter' && isset($data['newsletter_list'])) { foreach ($tokens as $name => $original) { switch ($name) { case 'list_name': $replacements[$original] = $sanitize ? filter_xss($data['newsletter_list']->title) : $data['newsletter_list']->title; break; case 'list_description': $replacements[$original] = $sanitize ? filter_xss($data['newsletter_list']->description) : $data['newsletter_list']->description; break; case 'list_category': $replacements[$original] = $sanitize ? filter_xss($data['newsletter_list']->category) : $data['newsletter_list']->category; break; } } } if ($type == 'newsletter' && isset($data['newsletter_subscriber'])) { foreach ($tokens as $name => $original) { switch ($name) { case 'confirmation_url': $replacements[$original] = url('newsletter/confirm/' . $data['newsletter_subscriber']->hash, array('absolute' => TRUE)); break; case 'subscription_ip': $replacements[$original] = $sanitize ? filter_xss($data['newsletter_subscriber']->ip) : $data['newsletter_subscriber']->ip; break; case 'unsubscribe_url': $replacements[$original] = url('newsletter/unsubscribe/' . $data['newsletter_subscriber']->hash, array('absolute' => TRUE)); break; case 'edit_subscription_url': $replacements[$original] = url('newsletter/edit/' . $data['newsletter_subscriber']->hash, array('absolute' => TRUE)); break; case 'subscriber_firstname': $replacements[$original] = $sanitize ? filter_xss($data['newsletter_subscriber']->firstname) : $data['newsletter_subscriber']->firstname; break; case 'subscriber_lastname': $replacements[$original] = $sanitize ? filter_xss($data['newsletter_subscriber']->lastname) : $data['newsletter_subscriber']->lastname; break; case 'subscriber_email': $replacements[$original] = $sanitize ? filter_xss($data['newsletter_subscriber']->email) : $data['newsletter_subscriber']->email; break; case 'subscription_time': $replacements[$original] = format_date($data['newsletter_subscriber']->created, 'long'); break; } } } return $replacements; } /** * Implements hook_mail(). */ function newsletter_mail($key, &$message, $params) { $template = isset($params['template']) ? $params['template'] : array(); $subscriber = isset($params['subscriber']) ? $params['subscriber'] : array(); $nodes = isset($params['nodes']) ? $params['nodes'] : array(); $list = isset($params['list']) ? $params['list'] : array(); $format = isset($params['format']) ? $params['format'] : ''; $newsletter = isset($params['newsletter']) ? $params['newsletter'] : array(); $template_body = field_get_items('newsletter_template', $template, 'field_newsletter_body'); if ($template_body) { $template_body = $template_body[0]; } switch ($key) { case 'test': $message['subject'] = t('Newsletter test e-mail'); $message['body'][] = t('This is a test e-mail generated by the Drupal Newsletter module. If you succesfully received this e-mail, it means that your server is capable of sending e-mails. Congratulations! You can now create lists, templates and subscribe users to them!'); $message['format'] = $params['format']; $message['body_format'] = 'plain_text'; break; case 'basic': $body = token_replace($template_body['value'], array('newsletter_subscriber' => $subscriber)); $message['subject'] = token_replace($template->subject, array()); $message['body'][] = $body; $message['body_format'] = $template_body['format']; $message['format'] = (isset($subscriber->receive_format) && $subscriber->receive_format) ? $subscriber->receive_format : $format; break; case 'automated': if (strpos($template_body['value'], '[repeat]') && strpos($template_body['value'], '[/repeat]')) { $body = explode('[repeat]', $template_body['value']); $head = $body[0]; $body = explode('[/repeat]', $body[1]); $foot = $body[1]; $items = array(); foreach ($nodes as $node) { $token_params = array('node' => $node); // Allow other modules to add token params for token_replace(). foreach (module_implements('newsletter_automated_token_params') as $module) { $function = $module . '_newsletter_automated_token_params'; $function($token_params); } $items[] = token_replace($body[0], $token_params); } $body = implode("\n", $items); $body = $head . $body . $foot; } else { $body = $template_body['value']; } $body = token_replace($body, array('newsletter_subscriber' => $subscriber, 'newsletter_list' => $list)); $message['subject'] = token_replace($template->subject, array()); $message['body'][] = $body; $message['format'] = (isset($subscriber->receive_format) && $subscriber->receive_format) ? $subscriber->receive_format : $format; $message['body_format'] = $template_body['format']; if (variable_get('newsletter_track_open_rate')) { $message['body'][] = newsletter_add_open_rate_image($subscriber->hash, $newsletter); } break; case 'custom': $body = token_replace($template_body['value'], array('newsletter_subscriber' => $subscriber)); $message['subject'] = token_replace($template->subject, array()); $message['body'][] = $body; $message['format'] = (isset($subscriber->receive_format) && $subscriber->receive_format) ? $subscriber->receive_format : $format; $message['body_format'] = $template_body['format']; if (variable_get('newsletter_track_open_rate')) { $message['body'][] = newsletter_add_open_rate_image($subscriber->hash, $newsletter); } break; } } /** * Implements hook_entity_info(). */ function newsletter_entity_info() { $return = array( 'newsletter_subscriber' => array( 'label' => t('Newsletter subscriber'), 'controller class' => 'NewsletterSubscriberController', 'access callback' => 'newsletter_entity_access', 'base table' => 'newsletter_subscriber', 'fieldable' => TRUE, 'entity keys' => array( 'id' => 'nsid', 'label' => 'email', ), 'bundles' => array( 'newsletter_subscriber' => array( 'label' => t('Newsletter subscriber'), 'admin' => array( 'path' => 'admin/config/media/newsletter/subscribers', 'access arguments' => array('administer newsletters'), ), ), ), ), 'newsletter_list' => array( 'label' => t('Newsletter list'), 'controller class' => 'NewsletterListController', 'access callback' => 'newsletter_entity_access', 'base table' => 'newsletter_list', 'fieldable' => TRUE, 'entity keys' => array( 'id' => 'nlid', 'label' => 'title', ), 'bundles' => array( 'newsletter_list' => array( 'label' => t('Newsletter list'), ), ), ), 'newsletter_template' => array( 'label' => t('Newsletter template'), 'controller class' => 'NewsletterTemplateController', 'access callback' => 'newsletter_entity_access', 'base table' => 'newsletter_template', 'fieldable' => TRUE, 'entity keys' => array( 'id' => 'ntid', 'label' => 'subject', ), 'bundles' => array( 'newsletter_template' => array( 'label' => t('Newsletter template'), 'admin' => array( 'path' => 'admin/config/media/newsletter/templates', 'access arguments' => array('administer newsletters'), ), ), ), ), 'newsletter_newsletter' => array( 'label' => t('Newsletter'), 'controller class' => 'NewsletterNewsletterController', 'access callback' => 'newsletter_entity_access', 'base table' => 'newsletter_newsletter', 'fieldable' => TRUE, 'entity keys' => array( 'id' => 'nnid', 'label' => 'title', ), 'bundles' => array( 'newsletter_newsletter' => array( 'label' => t('Newsletter'), ), ), ), ); return $return; } /** * Implements hook_field_attach_form(). */ function newsletter_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) { if ($entity_type == 'newsletter_subscriber') { $lang = $form['field_newsletter_list']['#language']; $list_ids = array_keys($form['field_newsletter_list'][$lang]['#options']); $lists = newsletter_list_load($list_ids); $exposed_lists = newsletter_exposed_lists(); foreach ($lists as $list) { if (in_array($list->nlid, $exposed_lists)) { $form['exposed']['exposed_' . $list->nlid] = array( '#type' => 'checkboxes', '#options' => newsletter_get_template_terms($list->field_newsletter_template[$lang][0]['target_id']), '#title' => t("@list's Configuration", array('@list' => $list->title)), '#default_value' => newsletter_get_default_exposed($entity, $list), ); } } } } /** * Implements hook_field_attach_presave(). */ function newsletter_field_attach_presave($entity_type, $entity) { if ($entity_type == 'newsletter_subscriber') { $exposed_lists = newsletter_exposed_lists(); foreach ($exposed_lists as $exposed_list) { $terms = isset($entity->{'exposed_' . $exposed_list}) ? $entity->{'exposed_' . $exposed_list} : array(); $tids = array(); foreach ($terms as $tid => $value) { if (!empty($value)) { $tids[] = $tid; } } $tids = !empty($tids) ? serialize($tids) : NULL; $lang = field_language($entity_type, $entity, 'field_newsletter_list'); foreach ($entity->field_newsletter_list[$lang] as $key => $list) { if ($list['target_id'] == $exposed_list) { $entity->field_newsletter_list[$lang][$key]['target_id_tids'] = $tids; } } } } } /** * Implements hook_entity_insert(). */ function newsletter_entity_insert($entity, $type) { newsletter_update_exposed_tids($entity, $type); } /** * Implements hook_entity_update(). */ function newsletter_entity_update($entity, $type) { newsletter_update_exposed_tids($entity, $type); } /** * Implementation of hook_views_api(). */ function newsletter_views_api() { return array( 'api' => 3, 'path' => drupal_get_path('module', 'newsletter') . '/includes/views' ); } /** * Implements hook_newsletter_list_sent(). */ function newsletter_newsletter_list_sent($message) { $newsletter = $message['params']['newsletter']; $newsletter->field_newsletter_body[LANGUAGE_NONE][0] = array( 'format' => $message['body_format'], 'summary' => text_summary($message['body'], $message['body_format']), 'value' => $message['body'], ); entity_get_controller('newsletter_newsletter')->save($newsletter); } /** * Since there is no hook_field_schema_alter() * we will have to update the exposed lists tid manually. * See #691932. */ function newsletter_update_exposed_tids($entity, $type) { if ($type == 'newsletter_subscriber') { $lists = field_get_items($type, $entity, 'field_newsletter_list'); foreach ($lists as $list) { if (isset($list['target_id_tids'])) { db_update('field_data_field_newsletter_list') ->fields(array('target_id_tids' => $list['target_id_tids'])) ->condition('entity_id', $entity->nsid) ->condition('field_newsletter_list_target_id', $list['target_id']) ->execute(); } } } } /** * Determines whether the given user has access to a subscriber/list/template. * * @see entity_access() */ function newsletter_entity_access($op, $entity = NULL, $account = NULL) { if (isset($entity->nlid) && $op == 'view') { // The entity is a newsletter list and we are in the subscribe form. return user_access('subscribe newsletters', $account); } return user_access('administer newsletters', $account); } /** * Access callback for user newsletter subscriptions editing. */ function newsletter_edit_subsdcriber_access($account) { return (($GLOBALS['user']->uid == $account->uid && user_access('subscribe newsletters')) || user_access('administer users')) && $account->uid > 0; } /** * Loads up the requested list. */ function newsletter_list_load($nlids = FALSE, $conditions = array(), $reset = FALSE) { if (is_numeric($nlids)) { $id = $nlids; $nlids = !empty($nlids) ? array($nlids) : array(); } $lists = entity_load('newsletter_list', $nlids, $conditions, $reset); return isset($id) ? $lists[$id] : $lists; } /** * Loads up the requested subscriber. */ function newsletter_subscriber_load($nsids = FALSE, $conditions = array(), $reset = FALSE) { if (is_numeric($nsids)) { $id = $nsids; $nsids = !empty($nsids) ? array($nsids) : array(); } $subscribers = entity_load('newsletter_subscriber', $nsids, $conditions, $reset); return isset($id) ? $subscribers[$id] : $subscribers; } /** * Loads up the requested template. */ function newsletter_template_load($ntids = FALSE, $conditions = array(), $reset = FALSE) { if (is_numeric($ntids)) { $id = $ntids; $ntids = !empty($ntids) ? array($ntids) : array(); } $templates = entity_load('newsletter_template', $ntids, $conditions, $reset); return isset($id) ? $templates[$id] : $templates; } /** * Loads up the requested newsletter. */ function newsletter_newsletter_load($nnids = FALSE, $conditions = array(), $reset = FALSE) { if (is_numeric($nnids)) { $id = $nnids; $nnids = !empty($nnids) ? array($nnids) : array(); } $newsletters = entity_load('newsletter_newsletter', $nnids, $conditions, $reset); return isset($id) ? $newsletters[$id] : $newsletters; } /** * Loads up the requested subscriber by its hash. */ function newsletter_subscriber_by_hash_load($hash) { $query = new EntityFieldQuery(); $entities = $query->entityCondition('entity_type', 'newsletter_subscriber') ->propertyCondition('hash', $hash) ->execute(); $keys = isset($entities['newsletter_subscriber']) ? array_keys($entities['newsletter_subscriber']) : array(); // Since we always expect to have one subscriber: return newsletter_subscriber_load(array_pop($keys)); } /** * Get the subscribers of a newsletter list. * * @param $nlid * The id of the newsletter list. * @param $filter * (boolean) Whether to filter out unconfirmed subscribers. * * @return * Array containg the subscriber full objects.Else empty array. */ function newsletter_subscribers_by_list($nlid, $filter = TRUE) { $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'newsletter_subscriber') ->fieldCondition('field_newsletter_list', 'target_id', $nlid); if ($filter) { $query->propertyCondition('confirmed', 1); } $entities = $query->execute(); return isset($entities['newsletter_subscriber']) ? newsletter_subscriber_load(array_keys($entities['newsletter_subscriber'])) : array(); } /** * Checks whether an email is registered to newsletter list or not. * * @return * boolean TRUE or FALSE. */ function newsletter_is_subscribed($mail = NULL) { if (!isset($mail)) { global $user; $mail = isset($user->mail) ? $user->mail : FALSE; } if ($mail) { $is_subscribed = db_query('SELECT email FROM {newsletter_subscriber} WHERE email = :mail', array(':mail' => $mail))->fetchField(); return (bool) $is_subscribed; } else { return FALSE; } } /** * Instantiates a new Newsletter class * according to http://drupal.org/node/608152. * * @return * A newsletter object. */ function newsletter_create($nlid = NULL, $ntid = NULL, $nnid = NULL) { if (isset($ntid)) { $newsletter = new NewsletterCustom($nlid, $ntid, $nnid); } elseif (isset($nlid) && !isset($ntid)) { $newsletter = new NewsletterAutomated($nlid); } else { $newsletter = new NewsletterBasic(); } return (object) $newsletter; } /* * Returns an image to be added to newsletter body * so we can calculate the open rate. * * @param $hash * Subscriber's personal hash. * @param $newsletter * The newsletter object. * * @return * An html image string. */ function newsletter_add_open_rate_image($hash, $newsletter) { $params = array( 'absolute' => TRUE, 'query' => array( 'source' => 'newsletter', 'nnid' => $newsletter->nnid, ), ); $url = url('newsletter/statistics/' . $hash, $params); $image = ""; return $image; } /** * Sets a watchdog message for the just sent newsletter. * * @param $id * The newsletter id. * @param $title * The subscriber's list title. * @param $mail * The subscriber's e-mail. * @param $result * The result from drupal_mail_system. */ function newsletter_set_watchdog($id, $title, $mail, $result) { watchdog('newsletter', 'Newsletter list with newsletter id @news_id and list name @list_name sent to @sub with status code @status.', array( '@news_id' => $id, '@list_name' => $title, '@sub' => $mail, '@status' => $result, ), WATCHDOG_ERROR); } /** * @return * An array of newsletter list ids with exposed templates. */ function newsletter_exposed_lists() { $query = new EntityFieldQuery(); $exposed_ntids = newsletter_exposed_templates(); if (empty($exposed_ntids)) { return array(); } $query->entityCondition('entity_type', 'newsletter_list') ->fieldCondition('field_newsletter_template', 'target_id', $exposed_ntids, 'IN'); $entities = $query->execute(); return isset($entities['newsletter_list']) ? array_keys($entities['newsletter_list']) : array(); } /** * @return * An array of newsletter template ids with exposed status. */ function newsletter_exposed_templates() { $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'newsletter_template') ->propertyCondition('exposed', 1); $entities = $query->execute(); return isset($entities['newsletter_template']) ? array_keys($entities['newsletter_template']) : array(); } /** * Fetches the terms for a template. * * @param * $ntid The template ntid. * * @return * An array of term names keyed by their tids. */ function newsletter_get_template_terms($ntid) { $terms = array(); $template = newsletter_template_load($ntid); $vocabularies = taxonomy_get_vocabularies(); foreach ($vocabularies as $vocabulary) { if ($vocabulary->machine_name == 'newsletter_categories') { continue; } $vocabulary_field = field_get_items('newsletter_template', $template, 'field_' . $vocabulary->machine_name); if ($vocabulary_field) { foreach ($vocabulary_field as $values) { $term = taxonomy_term_load($values['tid']); if ($term) { $terms[$term->tid] = $term->name; } } } } return $terms; } /** * Get a subscriber's exposed terms. */ function newsletter_get_default_exposed($subscriber, $list) { if (!isset($subscriber->nsid)) { return array(); } $tids = db_query('SELECT target_id_tids FROM {field_data_field_newsletter_list} WHERE entity_id = :nsid AND field_newsletter_list_target_id = :nlid', array(':nsid' => $subscriber->nsid, ':nlid' => $list->nlid))->fetchField(); if ($tids) { $tids = @unserialize($tids); if (is_array($tids)) { foreach ($tids as $tid) { $defaults[$tid] = $tid; } } } return isset($defaults) ? $defaults : array(); } /** * @return * An array of newsletter lists that are set to send with custom schedule. */ function newsletter_custom_send_rate_lists() { $lists = db_query('SELECT nlid, send_rate FROM {newsletter_list}')->fetchAll(); foreach ($lists as $list) { if (is_numeric($list->send_rate)) { $custom_lists[] = $list; } } return isset($custom_lists) ? $custom_lists : array(); } /** * Feedback to site administrator depending on newsletter send status. * * @param $statuses * An array containing status values set when a newsletter mail was sent. */ function newsletter_feedback($statuses) { if (is_array($statuses) && !empty($statuses)) { $success = 0; $error = 0; $no_items = 0; $no_subs = 0; foreach ($statuses as $status) { $status = ($status === 1 || $status === TRUE) ? 'success' : $status; switch ($status) { case 'No subscribers': $no_subs++; break; case 'No items': $no_items++; break; case 'success': $success++; break; default: $error++; } } if ($no_subs) { watchdog('newsletter', '%no_subs Newsletter Lists failed to send because no subscribers found subscribed to them', array('%no_subs' => $no_subs)); } if ($no_items) { watchdog('newsletter', '%no_items Newsletter Lists failed to send because no published nodes found for their terms', array('%no_items' => $no_items)); } if ($success) { watchdog('newsletter', '%success Newsletter Lists sent', array('%success' => $success)); } if ($error) { watchdog('newsletter', '%error Newsletter Lists failed to send.Check previous watchdog notices for more info', array('%error' => $error), WATCHDOG_ERROR); } } return; } /** * Add newsletter js file and settings. */ function newsletter_add_js() { static $added; if ($added) { return; } drupal_add_js(drupal_get_path('module', 'newsletter') . '/js/newsletter.js'); $lists = newsletter_exposed_lists(); if (!field_is_translatable('newsletter_subscriber', field_info_field('field_newsletter_list'))) { $lang = LANGUAGE_NONE; } else { $lang = language_default()->language; } drupal_add_js(array( 'exposed' => $lists, 'lang' => $lang), 'setting'); drupal_add_js('(function ($) {$(document).ready(function () { Drupal.behaviors.newsletter.subscribeForm(); });})(jQuery);', 'inline'); $added++; } /** * Loads up the form that is displayed to the newsletter block. */ function newsletter_subscribe_form($form, &$form_state) { global $user; $ajax = array( 'callback' => 'newsletter_subscribe_form_submit', 'wrapper' => 'newsletter-error', 'effect' => 'fade', 'progress' => array( 'type' => 'throbber', 'message' => NULL, ), 'event' => 'click', ); if (!isset($user->mail) || variable_get('newsletter_show_email_in_block', FALSE)) { $form['email'] = array( '#type' => 'textfield', '#default_value' => t('user@example.com'), '#size' => 20, '#required' => TRUE, ); } else { $form['logged-in'] = array( '#type' => 'hidden', '#value' => TRUE, ); } $form['newsletter-submit'] = array( '#type' => 'submit', '#value' => t('Subscribe'), '#prefix' => '
', '#suffix' => '
', '#ajax' => $ajax, ); return $form; } /** * Callback of newsletter subscription block.Degrades when js is off. * Validates e-mail and sends user to next step. */ function newsletter_subscribe_form_submit($form, &$form_state) { $is_ajax = isset($form_state['input']['ajax_page_state']); if (isset($form_state['values']['logged-in'])) { global $user; $mail = $user->mail; } elseif (!isset($form_state['values']['logged-in'])) { $mail = ($form_state['values']['email'] != t('user@example.com')) ? $form_state['values']['email'] : ''; } if (!valid_email_address($mail) || newsletter_is_subscribed($mail)) { $msg = t("This e-mail doesn't exist or you have already subscribed"); return $is_ajax ? '
' . $msg . '
' : drupal_set_message($msg, 'warning');; } $q = array( 'destination' => '', 'email' => $mail, ); $url = url('newsletter/subscribe', array('query' => $q)); if ($is_ajax) { return ""; } drupal_goto('newsletter/subscribe', array('query' => $q)); }