You are here

public function SpoolStorage::getMails in Simplenews 8

Same name and namespace in other branches
  1. 8.2 src/Spool/SpoolStorage.php \Drupal\simplenews\Spool\SpoolStorage::getMails()
  2. 3.x src/Spool/SpoolStorage.php \Drupal\simplenews\Spool\SpoolStorage::getMails()

This function allocates mails to be sent in current run.

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

Parameters

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

array $conditions: (Optional) Array of conditions which are applied to the query. If not set, status defaults to SpoolStorageInterface::STATUS_PENDING, SpoolStorageInterface::STATUS_IN_PROGRESS.

Return value

\Drupal\simplenews\Spool\SpoolListInterface A mail spool list.

Overrides SpoolStorageInterface::getMails

File

src/Spool/SpoolStorage.php, line 59

Class

SpoolStorage
Default database spool storage.

Namespace

Drupal\simplenews\Spool

Code

public function getMails($limit = self::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(
      SpoolStorageInterface::STATUS_PENDING,
      SpoolStorageInterface::STATUS_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 = new Condition('OR');
  $statuses = is_array($conditions['status']) ? $conditions['status'] : array(
    $conditions['status'],
  );
  foreach ($statuses as $status) {
    if ($status == SpoolStorageInterface::STATUS_IN_PROGRESS) {
      $status_or
        ->condition((new Condition('AND'))
        ->condition('status', $status)
        ->condition('s.timestamp', $this
        ->getExpirationTime(), '<'));
    }
    else {
      $status_or
        ->condition('status', $status);
    }
  }
  unset($conditions['status']);
  $query = $this->connection
    ->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 ($this->lock
    ->acquire('simplenews_acquire_mail')) {

    // Get message id's
    // Allocate messages
    if ($limit > 0) {
      $query
        ->range(0, $limit);
    }
    foreach ($query
      ->execute() as $message) {
      if (mb_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
      $this
        ->updateMails(array_keys($messages), array(
        'status' => SpoolStorageInterface::STATUS_IN_PROGRESS,
      ));
    }
    $this->lock
      ->release('simplenews_acquire_mail');
  }

  /* END CRITICAL SECTION */
  return new SpoolList($messages);
}