You are here

function _message_delete_messages in Message 7

Delete messages that the reference to is still exists.

Parameters

$field_names: Array of fields names which holds the reference to the message.

$entity_id: The message referenced entity that were deleted.

$last_mid: The last Message ID we process.

$range: Optional;The number of message to process each time.

Return value

The last Message ID we process.

2 calls to _message_delete_messages()
message_entity_delete in ./message.module
Implements hook_entity_delete().
message_entity_delete_queue_worker in ./message.module
Queue API worker; Process a queue item.

File

./message.module, line 496
API functions to manipulate messages.

Code

function _message_delete_messages($field_names, $entity_id, $last_mid = 0, $range = NULL) {

  // List of messages to delete.
  $deletable_mids = array();

  // List of messages that might be deleted;
  // Messages with references to fields with multiple cardinality will be
  // stored in $check_mids in order to check if the entity being deleted
  // is the last one referenced by a given field.
  // Keyed by message ID, pointing to array of the relevant field names.
  $check_mids = array();
  foreach ($field_names as $field_name) {
    $field = field_info_field($field_name);
    $columns = array_keys($field['columns']);

    // Fetch messages with fields referencing the deleted entity.
    $query = new EntityFieldQuery();
    $query
      ->entityCondition('entity_type', 'message')
      ->propertyCondition('mid', $last_mid, '>')
      ->fieldCondition($field['field_name'], $columns[0], $entity_id);
    if ($range) {
      $query
        ->range(0, $range);
    }
    $result = $query
      ->execute();

    // Continue to next field if no such messages exist.
    if (empty($result['message'])) {
      continue;
    }

    // If the field has single cardinality it's safe to delete the
    // messages.
    if ($field['cardinality'] == 1) {
      $deletable_mids += array_keys($result['message']);
    }
    else {
      foreach ($result['message'] as $mid => $message) {

        // Each message ID is stored with the field it was found by, in
        // order to handle multiple fields.
        if (empty($check_mids[$mid])) {
          $check_mids[$mid] = array();
        }
        $check_mids[$mid][] = $field['field_name'];
      }
    }
  }

  // Check messages with multiple cardinality references; Only delete such
  // messages if the entity being deleted is the last one referenced by the
  // message.
  if ($check_mids) {
    $messages = message_load_multiple(array_keys($check_mids));
    foreach ($messages as $message) {
      foreach ($check_mids[$message->mid] as $field_name) {
        $field = field_info_field($field_name);
        $wrapper = entity_metadata_wrapper('message', $message);
        $count = $field['cardinality'] == 1 ? 1 : $wrapper->{$field_name}
          ->count();

        // The amount of entities actually referenced with this field.
        // Would have been nicer to use $count to determine the amount of
        // referenced entities, but it isn't necessary updated. So we have to
        // check each entity.
        $refrences_count = 0;
        for ($i = 0; $i < $count; $i++) {
          if ($wrapper->{$field_name}
            ->get($i)
            ->value()) {
            $refrences_count++;
          }
        }

        // Check if the message references exactly one entity with this field.
        if ($refrences_count == 1) {
          $deletable_mids[] = $message->mid;
        }
      }
    }
  }
  if ($deletable_mids) {
    message_delete_multiple($deletable_mids);
    return reset($deletable_mids);
  }
}