You are here

function message_subscribe_send_message in Message Subscribe 7

Process a message, and send to subscribed users.

$context = array(
  'node' => array(
    1,
  ),
  // The node author.
  'user' => array(
    10,
  ),
  // Related taxonomy terms.
  'taxonomy_term' => array(
    100,
    200,
    300,
  ),
);

Parameters

$entity_type: The entity type.

$entity: The entity object.

$message: The Message object.

$notify_options: Optional; Array of options to pass to message_notify_send_message() keyed by the notifier name.

$subscribe_options: Optional; Array with the following optional values:

  • "save message": Determine if the Message should be saved. Defaults to TRUE.
  • "skip context": Determine if extracting basic context should be skipped in message_subscribe_get_subscribers(). Defaults to FALSE.
  • "last uid": The last user ID to query.
  • "uids": Array of user IDs to be processed. Setting this, will cause skipping message_subscribe_get_subscribers() to get the subscribed users. For example: $subscribe_options['uids'] = array( 1 => array( 'notifiers' => array('email'), ), );
  • "range": The number of items to fetch in the query.
  • "end time": The timestamp of the time limit for the function to execute. Defaults to FALSE, meaning there is no time limitation.
  • "use queue": Determine if queue API should be used to
  • "queue": Set to TRUE to indicate the processing is done via a queue worker. see message_subscribe_queue_worker().
  • "entity access": Determine if access to view the entity should be applied when getting the list of subscribed users. Defaults to TRUE.
  • "notify blocked users": Determine whether blocked users should be notified. Typically this should be used in conjunction with "entity access" to ensure that blocked users don't receive notifications about entities which they used to have access to before they were blocked. Defaults to FALSE.
  • "notify message owner": Determines if the user that created the entity gets notified of their own action. If TRUE the author will get notified. Defaults to FALSE.

$context: Optional; Array keyed with the entity type and array of entity IDs as the value. For example, if the event is related to a node entity, the implementing module might pass along with the node itself, the node author and related taxonomy terms.

Return value

Message The message object.

5 calls to message_subscribe_send_message()
MessageSubscribeEmailSubscribersTest::testGetSubscribers in message_subscribe_email/message_subscribe_email.test
Test getting the subscribers list.
MessageSubscribeQueueTest::testProvidedUserIdsAreSplitAccordingToRangeValue in ./message_subscribe.test
Test that if we get a list of user IDs directly from the implementing module, the messages are sent respecting the range value.
MessageSubscribeQueueTest::testQueue in ./message_subscribe.test
Test base queue processing logic.
MessageSubscribeQueueTest::testQueueCron in ./message_subscribe.test
Test cron-based queue handling. These are very basic checks that ensure the cron worker callback functions as expected. No formal subscription processing is triggered here.
message_subscribe_queue_worker in ./message_subscribe.module
Queue API worker; Process a queue item.

File

./message_subscribe.module, line 71
Subscribe API for the Message and Message notify modules.

Code

function message_subscribe_send_message($entity_type, $entity, Message $message, $notify_options = array(), $subscribe_options = array(), $context = array()) {
  $use_queue = isset($subscribe_options['use queue']) ? $subscribe_options['use queue'] : variable_get('message_subscribe_use_queue', FALSE);
  $notify_message_owner = isset($subscribe_options['notify message owner']) ? $subscribe_options['notify message owner'] : variable_get('message_subscribe_notify_own_actions', FALSE);

  // Save message by default.
  $subscribe_options += array(
    'save message' => TRUE,
    'skip context' => FALSE,
    'last uid' => 0,
    'uids' => array(),
    'range' => $use_queue ? 100 : FALSE,
    'end time' => FALSE,
    'use queue' => $use_queue,
    'queue' => FALSE,
    'entity access' => TRUE,
    'notify blocked users' => FALSE,
    'notify message owner' => $notify_message_owner,
  );
  if (empty($message->mid) && $subscribe_options['save message']) {
    $message
      ->save();
  }
  if ($use_queue) {
    $queue = DrupalQueue::get('message_subscribe');
    list($id) = entity_extract_ids($entity_type, $entity);
  }
  if ($use_queue && empty($subscribe_options['queue'])) {
    if (empty($message->mid)) {
      throw new Exception('Cannot add a non-saved message to the queue.');
    }

    // Get the context once, so we don't need to process it every time
    // a worker claims the item.
    $context = $context ? $context : message_subscribe_get_basic_context($entity_type, $entity, $subscribe_options, $context);
    $subscribe_options['skip context'] = TRUE;

    // Add item to the queue.
    $task = array(
      'mid' => $message->mid,
      'entity_type' => $entity_type,
      'entity_id' => $id,
      'notify_options' => $notify_options,
      'subscribe_options' => $subscribe_options,
      'context' => $context,
      // Add the user ID for the queue.
      'uid' => $subscribe_options['last uid'],
    );

    // Exit now, as messages will be processed via queue API.
    return $queue
      ->createItem($task);
  }
  $message->message_subscribe = array();

  // Retrieve all users subscribed.
  $uids = array();
  if ($subscribe_options['uids']) {

    // We got a list of user IDs directly from the implementing module,
    // However we need to adhere to the range.
    // If 'last uid' is provided, we need to start from next 'uid' key in array.
    if (!empty($subscribe_options['last uid'])) {
      $index = array_search($subscribe_options['last uid'], array_keys($subscribe_options['uids'])) + 1;
    }
    else {
      $index = 0;
    }
    $uids = $subscribe_options['range'] ? array_slice($subscribe_options['uids'], $index, $subscribe_options['range'], TRUE) : $subscribe_options['uids'];
  }
  if (empty($uids) && !($uids = message_subscribe_get_subscribers($entity_type, $entity, $message, $subscribe_options, $context))) {

    // If we use a queue, it will be deleted.
    return $message;
  }
  foreach ($uids as $uid => $values) {
    $last_uid = $uid;

    // Clone the message in case it will need to be saved, it won't
    // overwrite the existing one.
    $cloned_message = clone $message;

    // Push a copy of the original message into the new one.
    $cloned_message->original = $message;
    unset($cloned_message->mid);
    $cloned_message->uid = $uid;
    $values += array(
      'notifiers' => array(),
    );

    // Send the message using the required notifiers.
    foreach ($values['notifiers'] as $notifier_name) {
      $options = !empty($notify_options[$notifier_name]) ? $notify_options[$notifier_name] : array();
      $options += array(
        'save on fail' => FALSE,
        'save on success' => FALSE,
      );
      message_notify_send_message($cloned_message, $options, $notifier_name);

      // Check we didn't timeout.
      if ($use_queue && $subscribe_options['queue']['end time'] && time() < $subscribe_options['queue']['end time']) {
        continue 2;
      }
    }
  }
  if ($use_queue) {

    // Add item to the queue.
    $task = array(
      'mid' => $message->mid,
      'entity_type' => $entity_type,
      'entity_id' => $id,
      'notify_options' => $notify_options,
      'subscribe_options' => $subscribe_options,
      'context' => $context,
      'uid' => $last_uid,
    );
    $task['subscribe_options']['last uid'] = $last_uid;

    // Create a new queue item, with the last user ID.
    $queue
      ->createItem($task);
  }
  return $message;
}