You are here

public function SpoolStorage::getMails in Simplenews 3.x

Same name and namespace in other branches
  1. 8.2 src/Spool/SpoolStorage.php \Drupal\simplenews\Spool\SpoolStorage::getMails()
  2. 8 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. Messages with status SpoolStorageInterface::STATUS_IN_PROGRESS will only be returned if the maximum send time has expired.

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 82

Class

SpoolStorage
Default database spool storage.

Namespace

Drupal\simplenews\Spool

Code

public function getMails($limit = self::UNLIMITED, array $conditions = []) {
  $spool_rows = [];

  // 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'] = [
      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 needs to
  // build an OR condition for them.
  $status_or = new Condition('OR');
  $statuses = is_array($conditions['status']) ? $conditions['status'] : [
    $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 mail spool
  // rows so that duplicate messages are not sent.
  if ($this->lock
    ->acquire('simplenews_acquire_mail')) {

    // Fetch mail spool rows.
    if ($limit > 0) {
      $query
        ->range(0, $limit);
    }
    foreach ($query
      ->execute() as $spool_row) {
      $spool_rows[$spool_row->msid] = $spool_row;
    }
    if (count($spool_rows) > 0) {

      // Set the state and the timestamp of the mails.
      $this
        ->updateMails(array_keys($spool_rows), SpoolStorageInterface::STATUS_IN_PROGRESS);
    }
    $this->lock
      ->release('simplenews_acquire_mail');
  }

  /* END CRITICAL SECTION */
  return $this
    ->createSpoolList($spool_rows);
}