You are here

function _simplenews_send in Simplenews 5

Send the newsletter

2 calls to _simplenews_send()
simplenews_cron in ./simplenews.module
Implementation of hook_cron().
simplenews_nodeapi in ./simplenews.module
Implementation of hook_nodeapi().

File

./simplenews.module, line 1217

Code

function _simplenews_send($timer = FALSE) {
  $max_time = variable_get('simplenews_time', 5);
  if ($timer && $max_time == 0) {
    return;
  }
  if ($max_time == 0) {
    $max_time = 1;
  }
  $max_time = $max_time - 0.5;
  $start_time = simplenews_time();
  if (!$timer) {
    $throttle = variable_get('simplenews_throttle', 20);
    static $counter = 0;
  }
  $result = db_query(db_rewrite_sql('SELECT n.nid, s.vid, s.tid, n.created FROM {node} n INNER JOIN {simplenews_newsletters} s ON n.nid = s.nid WHERE s.s_status = %d ORDER BY n.created ASC'), 1);
  while ($nid = db_fetch_object($result)) {
    $term = taxonomy_get_term($nid->tid);

    // To prevent empty emails from being send, we interrupt the send action and try again next time.
    if (!($node = simplenews_node_prepare($nid->nid, $nid->vid, $nid->tid))) {
      watchdog('newsletter', t('Empty newsletter node loaded (nid = @nid; vid = @vid). Please report in the simplenews issue queue.', array(
        '@nid' => $nid->nid,
        '@vid' => $nid->vid,
      )), WATCHDOG_ERROR);
      return;
    }
    $result2 = db_query('SELECT s.mail, s.snid FROM {simplenews_subscriptions} s INNER JOIN {simplenews_snid_tid} t ON s.snid = t.snid WHERE s.s_status = %d AND s.a_status = %d AND t.tid = %d ORDER BY s.snid ASC', 0, 1, $nid->tid);
    while ($mail = db_fetch_object($result2)) {
      $hash = _simplenews_generate_hash($mail->mail, $mail->snid, $nid->tid);

      // Add themable footer to message as this changes per user.
      $user_node = drupal_clone($node);
      $user_node->to = $mail->mail;
      $user_node = theme('simplenews_newsletter_footer', $user_node, $hash);
      $counter++;
      if (simplenews_mail_send($user_node)) {

        // TODO: This looks like it may choke if you were sending multiple
        // newsletters through cron. Should move s_status to snid_tid table
        // or somewhere else to see which newsletter has been sent.
        db_query('UPDATE {simplenews_subscriptions} SET s_status = %d WHERE snid = %d', 1, $mail->snid);

        // don't send mails too fast, servers may choke. Wait for 10 ms.
        usleep(10000);
      }
      else {
        watchdog('newsletter', t('Newsletter %title could not be sent to %email.', array(
          '%title' => $user_node->title,
          '%email' => $mail->mail,
        )), WATCHDOG_ERROR);
      }
      if ($timer) {
        $int_time = simplenews_time();
      }
      else {
        if ($counter < $throttle) {
          $int_time = $start_time;
        }
        else {
          return;
        }
      }
      if (!($int_time - $start_time < $max_time)) {
        return;
      }
    }
    db_query('UPDATE {simplenews_subscriptions} SET s_status = %d', 0);
    db_query('UPDATE {simplenews_newsletters} SET s_status = %d WHERE nid = %d', 2, $node->nid);
    if ($timer) {
      $int_time = simplenews_time();
    }
    else {
      $int_time = $start_time;
    }
    if (!($int_time - $start_time < $max_time)) {
      return;
    }
  }
}