123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926 |
- <?php
- function simplenews_add_node_to_spool($node) {
-
-
-
- $select = db_select('simplenews_subscriber', 's');
- $select->innerJoin('simplenews_subscription', 't', 's.snid = t.snid');
- $select->addField('s', 'mail');
- $select->addField('s', 'snid');
- $select->addField('t', 'tid');
- $select->addExpression($node->nid, 'nid');
- $select->addExpression(SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED, 'status');
- $select->addExpression(REQUEST_TIME, 'timestamp');
- $select->condition('t.tid', $node->simplenews->tid);
- $select->condition('t.status', SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED);
- $select->condition('s.activated', SIMPLENEWS_SUBSCRIPTION_ACTIVE);
- db_insert('simplenews_mail_spool')
- ->from($select)
- ->execute();
-
- simplenews_newsletter_update_sent_status($node);
-
- module_invoke_all('simplenews_spooled', $node);
- }
- function simplenews_mail_attempt_immediate_send(array $conditions = array(), $use_batch = TRUE) {
- if (variable_get('simplenews_use_cron', TRUE)) {
- return FALSE;
- }
- if ($use_batch) {
-
-
- $throttle = variable_get('simplenews_throttle', 20);
- $spool_count = simplenews_count_spool($conditions);
- $num_operations = ceil($spool_count / $throttle);
- $operations = array();
- for ($i = 0; $i < $num_operations; $i++) {
- $operations[] = array('simplenews_mail_spool', array($throttle, $conditions));
- }
-
- $operations[] = array('simplenews_clear_spool', array());
- $operations[] = array('simplenews_send_status_update', array());
- $batch = array(
- 'operations' => $operations,
- 'title' => t('Sending mails'),
- 'file' => drupal_get_path('module', 'simplenews') . '/includes/simplenews.mail.inc',
- );
- batch_set($batch);
- }
- else {
-
- simplenews_mail_spool(SIMPLENEWS_UNLIMITED, $conditions);
- simplenews_clear_spool();
- simplenews_send_status_update();
- }
- return TRUE;
- }
- function simplenews_send_test($node, $test_addresses) {
-
- if ($original_session = drupal_save_session()) {
- drupal_save_session(FALSE);
- }
-
- $original_user = $GLOBALS['user'];
- $GLOBALS['user'] = drupal_anonymous_user();
-
-
-
-
- $recipients = array('anonymous' => array(), 'user' => array());
- foreach ($test_addresses as $mail) {
- $mail = trim($mail);
- if (!empty($mail)) {
- $subscriber = simplenews_subscriber_load_by_mail($mail);
- if (!$subscriber) {
-
-
- $subscriber = new stdClass();
- $subscriber->uid = 0;
- $subscriber->mail = $mail;
- $subscriber->language = $GLOBALS['language']->language;
- }
- if (!empty($account->uid)) {
- $recipients['user'][] = $account->name . ' <' . $mail . '>';
- }
- else {
- $recipients['anonymous'][] = $mail;
- }
- $source = new SimplenewsSourceNode($node, $subscriber);
- $source->setKey('test');
- $result = simplenews_send_source($source);
- }
- }
- if (count($recipients['user'])) {
- $recipients_txt = implode(', ', $recipients['user']);
- drupal_set_message(t('Test newsletter sent to user %recipient.', array('%recipient' => $recipients_txt)));
- }
- if (count($recipients['anonymous'])) {
- $recipients_txt = implode(', ', $recipients['anonymous']);
- drupal_set_message(t('Test newsletter sent to anonymous %recipient.', array('%recipient' => $recipients_txt)));
- }
- $GLOBALS['user'] = $original_user;
- if ($original_session) {
- drupal_save_session(TRUE);
- }
- }
- function simplenews_send_source(SimplenewsSourceInterface $source) {
- $params['simplenews_source'] = $source;
-
- $message = drupal_mail('simplenews', $source->getKey(), $source->getRecipient(), $source->getLanguage(), $params, $source->getFromFormatted());
-
- if (variable_get('simplenews_debug', FALSE)) {
- if ($message['result']) {
- watchdog('simplenews', 'Outgoing email. Message type: %type<br />Subject: %subject<br />Recipient: %to', array('%type' => $source->getKey(), '%to' => $message['to'], '%subject' => $message['subject']), WATCHDOG_DEBUG);
- }
- else {
- watchdog('simplenews', 'Outgoing email failed. Message type: %type<br />Subject: %subject<br />Recipient: %to', array('%type' => $source->getKey(), '%to' => $message['to'], '%subject' => $message['subject']), WATCHDOG_ERROR);
- }
- }
-
- if ($message['result']) {
- $result = array(
- 'status' => SIMPLENEWS_SPOOL_DONE,
- 'error' => FALSE,
- );
- }
- else {
-
-
- $result = array(
- 'status' => SIMPLENEWS_SPOOL_PENDING,
- 'error' => TRUE,
- );
- }
- return $result;
- }
- function simplenews_mail_spool($limit = SIMPLENEWS_UNLIMITED, array $conditions = array()) {
- $check_counter = 0;
-
- $spool_list = simplenews_get_spool($limit, $conditions);
- if ($spool_list) {
-
- simplenews_impersonate_user(drupal_anonymous_user());
- $count_fail = $count_success = 0;
- $sent = array();
- _simplenews_measure_usec(TRUE);
- $spool = new SimplenewsSpool($spool_list);
- while ($source = $spool->nextSource()) {
- $source->setKey('node');
- $result = simplenews_send_source($source);
-
-
-
- foreach ($spool->getProcessed() as $msid => $row) {
- $row_result = isset($row->result) ? $row->result : $result;
- simplenews_update_spool(array($msid), $row_result);
- if ($row_result['status'] == SIMPLENEWS_SPOOL_DONE) {
- $count_success++;
- if (!isset($sent[$row->actual_nid])) {
- $sent[$row->actual_nid] = 1;
- }
- else {
- $sent[$row->actual_nid]++;
- }
- }
- if ($row_result['error']) {
- $count_fail++;
- }
- }
-
-
-
- if (++$check_counter >= SIMPLENEWS_SEND_CHECK_INTERVAL && ini_get('max_execution_time') > 0) {
- $check_counter = 0;
-
- $elapsed = _simplenews_measure_usec();
- if ($elapsed > SIMPLENEWS_SEND_TIME_LIMIT * ini_get('max_execution_time')) {
- watchdog('simplenews', 'Sending interrupted: PHP maximum execution time almost exceeded. Remaining newsletters will be sent during the next cron run. If this warning occurs regularly you should reduce the !cron_throttle_setting.', array('!cron_throttle_setting' => l(t('Cron throttle setting'), 'admin/config/simplenews/mail')), WATCHDOG_WARNING);
- break;
- }
- }
- }
-
-
- foreach ($spool->getProcessed() as $msid => $row) {
- $row_result = $row->result;
- simplenews_update_spool(array($msid), $row_result);
- if ($row_result['status'] == SIMPLENEWS_SPOOL_DONE) {
- $count_success++;
- if (isset($row->actual_nid)) {
- if (!isset($sent[$row->actual_nid])) {
- $sent[$row->actual_nid] = 1;
- }
- else {
- $sent[$row->actual_nid]++;
- }
- }
- }
- if ($row_result['error']) {
- $count_fail++;
- }
- }
-
- foreach ($sent as $nid => $count) {
- db_update('simplenews_newsletter')
- ->condition('nid', $nid)
- ->expression('sent_subscriber_count', 'sent_subscriber_count + :count', array(':count' => $count))
- ->execute();
- }
-
-
- if (function_exists('getrusage')) {
- watchdog('simplenews', '%success emails sent in %sec seconds, %fail failed sending.', array('%success' => $count_success, '%sec' => round(_simplenews_measure_usec(), 1), '%fail' => $count_fail));
- }
- else {
- watchdog('simplenews', '%success emails sent, %fail failed.', array('%success' => $count_success, '%fail' => $count_fail));
- }
- variable_set('simplenews_last_cron', REQUEST_TIME);
- variable_set('simplenews_last_sent', $count_success);
- simplenews_revert_user();
- return $count_success;
- }
- }
- function simplenews_save_spool($spool) {
- $status = isset($spool['status']) ? $spool['status'] : SIMPLENEWS_SPOOL_PENDING;
- $time = isset($spool['time']) ? $spool['time'] : REQUEST_TIME;
- db_insert('simplenews_mail_spool')
- ->fields(array(
- 'mail' => $spool['mail'],
- 'nid' => $spool['nid'],
- 'tid' => $spool['tid'],
- 'snid' => $spool['snid'],
- 'status' => $status,
- 'timestamp' => $time,
- 'data' => serialize($spool['data']),
- ))
- ->execute();
- }
- function simplenews_get_expiration_time() {
- $timeout = variable_get('simplenews_spool_progress_expiration', 3600);
- $expiration_time = REQUEST_TIME - $timeout;
- return $expiration_time;
- }
- function simplenews_get_spool($limit = SIMPLENEWS_UNLIMITED, $conditions = array()) {
- $messages = array();
-
- if (!isset($conditions['status'])) {
- $conditions['status'] = array(SIMPLENEWS_SPOOL_PENDING, SIMPLENEWS_SPOOL_IN_PROGRESS);
- }
-
-
-
- $status_or = db_or();
- $statuses = is_array($conditions['status']) ? $conditions['status'] : array($conditions['status']);
- foreach ($statuses as $status) {
- if ($status == SIMPLENEWS_SPOOL_IN_PROGRESS) {
- $status_or->condition(db_and()
- ->condition('status', $status)
- ->condition('s.timestamp', simplenews_get_expiration_time(), '<')
- );
- }
- else {
- $status_or->condition('status', $status);
- }
- }
- unset($conditions['status']);
- $query = db_select('simplenews_mail_spool', 's')
- ->fields('s')
- ->condition($status_or)
- ->orderBy('s.timestamp', 'ASC');
-
- foreach ($conditions as $field => $value) {
- $query->condition($field, $value);
- }
-
-
-
- if (lock_acquire('simplenews_acquire_mail')) {
-
-
- if ($limit > 0) {
- $query->range(0, $limit);
- }
- foreach ($query->execute() as $message) {
- if (drupal_strlen($message->data)) {
- $message->data = unserialize($message->data);
- }
- else {
- $message->data = simplenews_subscriber_load_by_mail($message->mail);
- }
- $messages[$message->msid] = $message;
- }
- if (count($messages) > 0) {
-
- simplenews_update_spool(
- array_keys($messages),
- array('status' => SIMPLENEWS_SPOOL_IN_PROGRESS)
- );
- }
- lock_release('simplenews_acquire_mail');
- }
-
- return $messages;
- }
- function simplenews_update_spool($msids, $data) {
- db_update('simplenews_mail_spool')
- ->condition('msid', $msids)
- ->fields(array(
- 'status' => $data['status'],
- 'error' => isset($result['error']) ? (int)$data['error'] : 0,
- 'timestamp' => REQUEST_TIME,
- ))
- ->execute();
- }
- function simplenews_count_spool(array $conditions = array()) {
-
- if (!isset($conditions['status'])) {
- $conditions['status'] = array(SIMPLENEWS_SPOOL_PENDING, SIMPLENEWS_SPOOL_IN_PROGRESS);
- }
- $query = db_select('simplenews_mail_spool');
-
- foreach ($conditions as $field => $value) {
- if ($field == 'status') {
- if (!is_array($value)) {
- $value = array($value);
- }
- $status_or = db_or();
- foreach ($value as $status) {
-
- if ($status == SIMPLENEWS_SPOOL_IN_PROGRESS) {
- $status_or->condition(db_and()
- ->condition('status', $status)
- ->condition('timestamp', simplenews_get_expiration_time(), '<')
- );
- }
- else {
- $status_or->condition('status', $status);
- }
- }
- $query->condition($status_or);
- }
- else {
- $query->condition($field, $value);
- }
- }
- $query->addExpression('COUNT(*)', 'count');
- return (int)$query
- ->execute()
- ->fetchField();
- }
- function simplenews_clear_spool() {
- $expiration_time = REQUEST_TIME - variable_get('simplenews_spool_expire', 0) * 86400;
- return db_delete('simplenews_mail_spool')
- ->condition('status', SIMPLENEWS_SPOOL_DONE)
- ->condition('timestamp', $expiration_time, '<=')
- ->execute();
- }
- function simplenews_delete_spool(array $conditions) {
- $query = db_delete('simplenews_mail_spool');
- foreach ($conditions as $condition => $value) {
- $query->condition($condition, $value);
- }
- return $query->execute();
- }
- function simplenews_send_status_update() {
- $counts = array();
- $sum = array();
- $send = array();
-
- $query = db_select('simplenews_newsletter', 's');
- $query->innerJoin('node', 'n', 's.nid = n.nid');
- $query->fields('s', array('nid', 'tid'))
- ->fields('n', array('tnid'))
- ->condition('s.status', SIMPLENEWS_STATUS_SEND_PENDING);
- foreach ($query->execute() as $newsletter) {
- $counts[$newsletter->tnid][$newsletter->nid] = simplenews_count_spool(array('nid' => $newsletter->nid));
- }
-
- foreach ($counts as $tnid => $node_count) {
-
-
- $sum[$tnid] = array_sum($node_count);
- foreach ($node_count as $nid => $count) {
-
- if ($tnid != '0' && $sum[$tnid] == '0') {
- $send[] = $nid;
- }
-
- elseif ($tnid == '0' && $count == '0') {
- $send[] = $nid;
- }
- }
- }
-
- if (!empty($send)) {
- foreach ($send as $nid) {
- db_update('simplenews_newsletter')
- ->condition('nid', $nid)
- ->fields(array('status' => SIMPLENEWS_STATUS_SEND_READY))
- ->execute();
- }
- }
- }
- function _simplenews_set_from() {
- $address_default = variable_get('site_mail', ini_get('sendmail_from'));
- $name_default = variable_get('site_name', 'Drupal');
- $address = variable_get('simplenews_from_address', $address_default);
- $name = variable_get('simplenews_from_name', $name_default);
-
- $formatted_address = (drupal_substr(PHP_OS, 0, 3) == 'WIN') ? $address : '"'. addslashes(mime_header_encode($name)) .'" <'. $address .'>';
- return array(
- 'address' => $address,
- 'formatted' => $formatted_address,
- );
- }
- function simplenews_html_to_text($text, $inline_hyperlinks = TRUE) {
-
-
-
-
- if ($inline_hyperlinks) {
- $pattern = '@<a[^>]+?href="([^"]*)"[^>]*?>(.+?)</a>@is';
- $text = preg_replace_callback($pattern, '_simplenews_absolute_mail_urls', $text);
- }
-
- $preg = _simplenews_html_replace();
- $text = preg_replace(array_keys($preg), array_values($preg), $text);
-
- return drupal_html_to_text($text);
- }
- function _simplenews_absolute_mail_urls($match) {
- global $base_url, $base_path;
- $regexp = &drupal_static(__FUNCTION__);
- $url = $label = '';
- if ($match) {
- if (empty($regexp)) {
- $regexp = '@^' . preg_quote($base_path, '@') . '@';
- }
- list(, $url, $label) = $match;
- $url = strpos($url, '://') ? $url : preg_replace($regexp, $base_url . '/', $url);
-
-
- if (strpos($label, '...') === drupal_strlen($label) - 3) {
-
- $label = drupal_substr($label, 0, drupal_strlen($label) - 3);
- }
- if (strpos($url, $label) !== FALSE) {
- return $url;
- }
- return $label . ' ' . $url;
- }
- }
- function _simplenews_html_replace() {
- return array(
- '/"/i' => '"',
- '/>/i' => '>',
- '/</i' => '<',
- '/&/i' => '&',
- '/©/i' => '(c)',
- '/™/i' => '(tm)',
- '/“/' => '"',
- '/”/' => '"',
- '/–/' => '-',
- '/’/' => "'",
- '/&/' => '&',
- '/©/' => '(c)',
- '/™/' => '(tm)',
- '/—/' => '--',
- '/“/' => '"',
- '/”/' => '"',
- '/•/' => '*',
- '/®/i' => '(R)',
- '/•/i' => '*',
- '/€/i' => 'Euro ',
- );
- }
- function _simplenews_measure_usec($start = FALSE) {
-
- if (!function_exists('getrusage')) {
- return;
- }
- $start_time = &drupal_static(__FUNCTION__);
- $usage = getrusage();
- $now = (float)($usage['ru_stime.tv_sec'] . '.' . $usage['ru_stime.tv_usec']) + (float)($usage['ru_utime.tv_sec'] . '.' . $usage['ru_utime.tv_usec']);
- if ($start) {
- $start_time = $now;
- return;
- }
- return $now - $start_time;
- }
- function simplenews_build_newsletter_mail(&$message, SimplenewsSourceInterface $source) {
-
- $message['headers'] = $source->getHeaders($message['headers']);
- $message['subject'] = $source->getSubject();
- $message['body']['body'] = $source->getBody();
- $message['body']['footer'] = $source->getFooter();
-
- if ($source->getFormat() == 'html') {
- $message['params']['plain'] = NULL;
- $message['params']['plaintext'] = $source->getPlainBody() . "\n" . $source->getPlainFooter();
- $message['params']['attachments'] = $source->getAttachments();
- }
- else {
- $message['params']['plain'] = TRUE;
- }
- }
- function simplenews_build_subscribe_mail(&$message, $params) {
- $context = $params['context'];
- $langcode = $message['language'];
-
- $message['headers']['From'] = $params['from']['formatted'];
- $message['subject'] = simplenews_subscription_confirmation_text('subscribe_subject', $langcode);
- $message['subject'] = token_replace($message['subject'], $context, array('sanitize' => FALSE));
- if (simplenews_user_is_subscribed($context['simplenews_subscriber']->mail, $context['category']->tid)) {
- $body = simplenews_subscription_confirmation_text('subscribe_subscribed', $langcode);
- }
- else {
- $body = simplenews_subscription_confirmation_text('subscribe_unsubscribed', $langcode);
- }
- $message['body'][] = token_replace($body, $context, array('sanitize' => FALSE));
- }
- function simplenews_build_combined_mail(&$message, $params) {
- $context = $params['context'];
- $changes = $context['changes'];
- $langcode = $message['language'];
-
- $message['headers']['From'] = $params['from']['formatted'];
- $message['subject'] = simplenews_subscription_confirmation_text('combined_subject', $langcode);
- $message['subject'] = token_replace($message['subject'], $context, array('sanitize' => FALSE));
- $changes_list = '';
- $actual_changes = 0;
- foreach (simplenews_confirmation_get_changes_list($context['simplenews_subscriber'], $changes, $langcode) as $tid => $change) {
- $changes_list .= ' - ' . $change . "\n";
-
- $subscribed = simplenews_user_is_subscribed($context['simplenews_subscriber']->mail, $tid);
- if ($changes[$tid] == 'subscribe' && !$subscribed || $changes[$tid] == 'unsubscribe' && $subscribed) {
- $actual_changes++;
- }
- }
-
-
- $body_key = $actual_changes ? 'combined_body' : 'combined_body_unchanged';
- $body = simplenews_subscription_confirmation_text($body_key, $langcode);
-
- $body = str_replace('[changes-list]', $changes_list, $body);
- $message['body'][] = token_replace($body, $context, array('sanitize' => FALSE));
- }
- function simplenews_build_unsubscribe_mail(&$message, $params) {
- $context = $params['context'];
- $langcode = $message['language'];
-
- $message['headers']['From'] = $params['from']['formatted'];
- $message['subject'] = simplenews_subscription_confirmation_text('subscribe_subject', $langcode);
- $message['subject'] = token_replace($message['subject'], $context, array('sanitize' => FALSE));
- if (simplenews_user_is_subscribed($context['simplenews_subscriber']->mail, $context['category']->tid)) {
- $body = simplenews_subscription_confirmation_text('unsubscribe_subscribed', $langcode);
- $message['body'][] = token_replace($body, $context, array('sanitize' => FALSE));
- }
- else {
- $body = simplenews_subscription_confirmation_text('unsubscribe_unsubscribed', $langcode);
- $message['body'][] = token_replace($body, $context, array('sanitize' => FALSE));
- }
- }
- class SimplenewsHTMLTestingMailSystem implements MailSystemInterface {
-
- public function format(array $message) {
-
- $message['body'] = implode("\n\n", $message['body']);
-
- $message['body'] = drupal_wrap_mail($message['body']);
- return $message;
- }
-
- public function mail(array $message) {
- $captured_emails = variable_get('drupal_test_email_collector', array());
- $captured_emails[] = $message;
-
-
- variable_set('drupal_test_email_collector', $captured_emails);
- return TRUE;
- }
- }
|