You are here

function simplenews_get_spool in Simplenews 7.2

Same name and namespace in other branches
  1. 6.2 includes/simplenews.mail.inc \simplenews_get_spool()
  2. 6 simplenews.module \simplenews_get_spool()
  3. 7 includes/simplenews.mail.inc \simplenews_get_spool()

This function allocates messages to be sent in current run.

Drupal acquire_lock guarantees that no concurrency issue happened. If the message status is SIMPLENEWS_SPOOL_IN_PROGRESS but the maximum send time has expired, the message id will be returned as a message which is not allocated to another process.

Parameters

$limit: (Optional) The maximum number of mails to load from the spool. Defaults to unlimited.

$conditions: (Optional) Array of conditions which are applied to the query. If not set, status defaults to SIMPLENEWS_SPOOL_PENDING, SIMPLENEWS_SPOOL_IN_PROGRESS.

Return value

An array of message ids to be sent in the current run.

Related topics

3 calls to simplenews_get_spool()
SimplenewsSendTestCase::testDelete in tests/simplenews.test
Create a newsletter, send mails and then delete.
SimplenewsSendTestCase::testProgrammaticNewsletter in tests/simplenews.test
Creates and sends a node using the API.
simplenews_mail_spool in includes/simplenews.mail.inc
Send simplenews newsletters from the spool.

File

includes/simplenews.mail.inc, line 385
Simplenews email send and spool handling

Code

function simplenews_get_spool($limit = SIMPLENEWS_UNLIMITED, $conditions = array()) {
  $messages = array();

  // Continue to support 'nid' as a condition.
  if (!empty($conditions['nid'])) {
    $conditions['entity_type'] = 'node';
    $conditions['entity_id'] = $conditions['nid'];
    unset($conditions['nid']);
  }

  // Add default status condition if not set.
  if (!isset($conditions['status'])) {
    $conditions['status'] = array(
      SIMPLENEWS_SPOOL_PENDING,
      SIMPLENEWS_SPOOL_IN_PROGRESS,
    );
  }

  // Special case for the status condition, the in progress actually only
  // includes spool items whose locking time has expired. So this need to build
  // an OR condition for them.
  $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');

  // Add conditions.
  foreach ($conditions as $field => $value) {
    $query
      ->condition($field, $value);
  }

  /* BEGIN CRITICAL SECTION */

  // The semaphore ensures that multiple processes get different message ID's,
  // so that duplicate messages are not sent.
  if (lock_acquire('simplenews_acquire_mail')) {

    // Get message id's
    // Allocate messages
    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) {

      // Set the state and the timestamp of the messages
      simplenews_update_spool(array_keys($messages), array(
        'status' => SIMPLENEWS_SPOOL_IN_PROGRESS,
      ));
    }
    lock_release('simplenews_acquire_mail');
  }

  /* END CRITICAL SECTION */
  return $messages;
}