You are here

function message_entity_delete in Message 8

Same name and namespace in other branches
  1. 7 message.module \message_entity_delete()

Implements hook_entity_delete().

Handles messages deletion when referenced entities are being deleted.

File

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

Code

function message_entity_delete(EntityInterface $entity) {
  $type = $entity
    ->getEntityType()
    ->id();
  if ($type == 'message') {

    // Why not message?
    return;
  }
  $types = \Drupal::config('message.settings')
    ->get('delete_on_entity_delete');
  if (!$types || !in_array($type, $types)) {
    return;
  }

  // List of messages to delete.
  $deletable_mids = [];

  // 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 = [];

  /** @var \Drupal\Core\Field\FieldStorageDefinitionInterface[] $fields */
  $fields = \Drupal::entityTypeManager()
    ->getStorage('field_storage_config')
    ->loadMultiple();

  // Search for fields in which messages referenced the deleted entity.
  foreach ($fields as $field) {
    if ($field
      ->getTargetEntityTypeId() != 'message') {

      // This field isn't used in any message.
      continue;
    }

    // Only delete messages due to referenced entity or referenced taxonomy term
    // deletion.
    if ($field
      ->getType() != 'entity_reference') {
      continue;
    }

    // Only delete references if the referenced entity is the correct type.
    if ($field
      ->getSetting('target_type') != $entity
      ->getEntityTypeId()) {
      continue;
    }
    $query = \Drupal::entityQuery('message');
    $results = $query
      ->condition($field
      ->getName(), $entity
      ->id())
      ->execute();
    if (empty($results)) {
      continue;
    }
    if ($field
      ->getCardinality() == 1) {
      $deletable_mids = array_merge($deletable_mids, $results);
    }
    else {
      foreach ($results as $id) {
        $check_mids[$id][] = $field
          ->getName();
      }
    }
  }
  $deletable_mids = array_values($deletable_mids);

  // 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) {
    $queue_set = [];
    $count = 0;
    $num_mids = count($check_mids);
    foreach ($check_mids as $id => $field_names) {

      // If it already qualified for deletion based on one field, there's no
      // need to check multi-valued fields.
      if (!in_array($id, $deletable_mids)) {
        $queue_set[$id] = $field_names;
      }
      if ($queue_set && ($count % MessagePurgeInterface::MESSAGE_DELETE_SIZE == 0 || $count == $num_mids)) {
        \Drupal::queue('message_check_delete')
          ->createItem($queue_set);
        $queue_set = [];
      }
      $count++;
    }
  }
  if ($deletable_mids) {
    $num_items = ceil(count($deletable_mids) / MessagePurgeInterface::MESSAGE_DELETE_SIZE);
    for ($i = 0; $i < $num_items; $i++) {
      $queue_set = array_slice($deletable_mids, $i * MessagePurgeInterface::MESSAGE_DELETE_SIZE, MessagePurgeInterface::MESSAGE_DELETE_SIZE);
      \Drupal::queue('message_delete')
        ->createItem($queue_set);
    }
  }
}