newsletter.module in Newsletter 7.2
Same filename and directory in other branches
Defines menu items for newsletter administration, permissions and basic drupal hooks.
File
newsletter.moduleView source
<?php
/**
* @file
* Defines menu items for newsletter administration,
* permissions and basic drupal hooks.
*/
/**
* Implements hook_menu().
*/
function newsletter_menu() {
$items = array();
$items['admin/config/media/newsletter'] = array(
'title' => 'Newsletters',
'description' => 'Manage newsletters, subscribers, and settings.',
'access arguments' => array(
'administer newsletters',
),
);
$items['admin/config/media/newsletter/configure'] = array(
'title' => 'Settings',
'description' => 'Configure newsletter lists.',
'access arguments' => array(
'administer newsletters',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'newsletter_configure_form',
),
'file' => 'includes/newsletter.admin.inc',
'weight' => 5,
);
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.'),
);
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}\n WHERE (send_again = CURDATE() OR send_again IS NULL)\n 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_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 = array(
'field_name' => 'field_' . $vocabulary->machine_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_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_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_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() {
$entities = array(
'newsletter' => array(
'label' => t('Newsletter'),
'controller class' => 'NewsletterController',
'base table' => 'newsletter',
'fieldable' => TRUE,
'entity keys' => array(
'id' => 'newsletter_id',
'label' => 'title',
),
'bundles' => array(
'newsletter' => array(
'label' => t('Newsletter'),
),
),
),
);
return $entities;
}
/**
* Implements hook_views_api().
*/
function newsletter_views_api() {
return array(
'api' => 3,
'path' => drupal_get_path('module', 'newsletter') . '/includes/views',
);
}
/**
* Loads a newsletter by ID.
*/
function newsletter_load($newsletter_id) {
if (empty($newsletter_id)) {
return FALSE;
}
$newsletters = newsletter_load_multiple(array(
$newsletter_id,
), array());
return $newsletters ? reset($newsletters) : FALSE;
}
/**
* Loads multiple newsletters by ID or based on a set of matching conditions.
*
* @see entity_load()
*
* @param $newsletter_ids
* An array of newsletter IDs.
* @param $conditions
* Deprecated. use EntityFieldQuery instead.
* @param $reset
* Whether to reset the internal template loading cache.
*
* @return
* An array of newsletter template objects indexed by nsid.
*/
function newsletter_load_multiple($newsletter_ids = array(), $conditions = array(), $reset = FALSE) {
if (empty($newsletter_ids) && empty($conditions)) {
return array();
}
return entity_load('newsletter', $newsletter_ids, $conditions, $reset);
}
/**
* Saves a newsletter.
*
* @param $newsletter
* The full newsletter object to save.
*
* @return
* SAVED_NEW or SAVED_UPDATED depending on the operation performed.
*/
function newsletter_save($newsletter) {
return entity_get_controller('newsletter')
->save($newsletter);
}
/**
* 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;
}
/**
* 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;
}