You are here

entity_usage.module in Entity Usage 8.3

Same filename and directory in other branches
  1. 8.4 entity_usage.module
  2. 8 entity_usage.module
  3. 8.2 entity_usage.module

File

entity_usage.module
View source
<?php

/**
 * @file
 * Contains entity_usage.module.
 */
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\entity_usage\EntityUpdateManager;
use Drupal\entity_usage\EntityUsageSourceLevel;
use Drupal\field\FieldConfigInterface;
use Drupal\field\FieldStorageConfigInterface;

/**
 * Implements hook_help().
 */
function entity_usage_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {

    // Main module help for the entity_usage module.
    case 'help.page.entity_usage':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('Track usage of entities referenced by other entities.') . '</p>';
      return $output;
    default:
  }
}

/**
 * Implements hook_entity_insert().
 */
function entity_usage_entity_insert(EntityInterface $entity) {
  if (EntityUsageSourceLevel::isTopLevel($entity)) {
    \Drupal::service('entity_usage.entity_update_manager')
      ->addTopLevelSource($entity, EntityUpdateManager::OPERATION_INSERT);
  }
}

/**
 * Implements hook_entity_update().
 */
function entity_usage_entity_update(EntityInterface $entity) {
  if (EntityUsageSourceLevel::isTopLevel($entity)) {
    \Drupal::service('entity_usage.entity_update_manager')
      ->addTopLevelSource($entity, EntityUpdateManager::OPERATION_UPDATE, clone $entity->original);
  }
}

/**
 * Implements hook_entity_predelete().
 */
function entity_usage_entity_predelete(EntityInterface $entity) {
  if (EntityUsageSourceLevel::isTopLevel($entity)) {
    \Drupal::service('entity_usage.entity_update_manager')
      ->addTopLevelSource($entity, EntityUpdateManager::OPERATION_ENTITY_DELETE);
  }
}

/**
 * Implements hook_entity_translation_delete().
 */
function entity_usage_entity_translation_delete(EntityInterface $translation) {
  if (EntityUsageSourceLevel::isTopLevel($translation)) {
    \Drupal::service('entity_usage.entity_update_manager')
      ->addTopLevelSource($translation, EntityUpdateManager::OPERATION_TRANSLATION_DELETE);
  }
}

/**
 * Implements hook_entity_revision_delete().
 */
function entity_usage_entity_revision_delete(EntityInterface $entity) {
  if (EntityUsageSourceLevel::isTopLevel($entity)) {
    \Drupal::service('entity_usage.entity_update_manager')
      ->addTopLevelSource($entity, EntityUpdateManager::OPERATION_REVISION_DELETE);
  }
}

/**
 * Implements hook_ENTITY_TYPE_delete() for field_storage_config.
 */
function entity_usage_field_storage_config_delete(EntityInterface $field) {
  _entity_usage_field_deleted_helper($field);
}

/**
 * Implements hook_ENTITY_TYPE_delete() for field_config.
 */
function entity_usage_field_config_delete(EntityInterface $field) {
  _entity_usage_field_deleted_helper($field);
}
function _entity_usage_field_deleted_helper(EntityInterface $field) {
  if ($field instanceof FieldConfigInterface || $field instanceof FieldStorageConfigInterface) {

    // When deleting a field on a top or middle-level entity, this might
    // generate stale data. Set the regeneration flag in that scenario.
    // @todo Consider: 1) Being less aggressive on reaching this conclusion, and
    // 2) in case a regeneration is indeed needed, maybe we should trigger a
    // queue to actually start regenerating, instead of just setting the flag?
    $entity_type = $field
      ->getTargetEntityTypeId();
    $top_level_types = EntityUsageSourceLevel::getTopLevelEntityTypes();
    $middle_level_types = EntityUsageSourceLevel::getMiddleLevelEntityTypes();
    if (in_array($entity_type, $top_level_types) || in_array($entity_type, $middle_level_types)) {
      \Drupal::state()
        ->set('entity_usage_needs_regeneration', TRUE);
    }
  }
}

/**
 * Implements hook_form_alter().
 */
function entity_usage_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form_object = $form_state
    ->getFormObject();
  if (!method_exists($form_object, 'getEntity')) {
    return;
  }

  /** @var \Drupal\Core\Entity\EntityInterface $entity */
  $entity = $form_object
    ->getEntity();
  if (empty($entity)) {
    return;
  }
  $config = \Drupal::config('entity_usage.settings');
  $edit_entity_types = $config
    ->get('edit_warning_message_entity_types') ?: [];
  $delete_entity_types = $config
    ->get('delete_warning_message_entity_types') ?: [];

  // Abort early if this entity is not configured to show any message.
  if (!in_array($entity
    ->getEntityTypeId(), $edit_entity_types) && !in_array($entity
    ->getEntityTypeId(), $delete_entity_types)) {
    return;
  }
  $usage_data = \Drupal::service('entity_usage.usage')
    ->listSources($entity);
  if (empty($usage_data)) {
    return;
  }

  // Check for the edit warning.
  if (method_exists($form_object, 'getOperation') && $form_object
    ->getOperation() === 'edit' && in_array($entity
    ->getEntityTypeId(), $edit_entity_types)) {
    $form['entity_usage_edit_warning'] = [
      '#theme' => 'status_messages',
      '#message_list' => [
        'warning' => [
          t('Modifications on this form will affect all <a href="@usage_url" target="_blank">existing usages</a> of this entity.', [
            '@usage_url' => Url::fromRoute('entity_usage.usage_list', [
              'entity_type' => $entity
                ->getEntityTypeId(),
              'entity_id' => $entity
                ->id(),
            ])
              ->toString(),
          ]),
        ],
      ],
      '#status_headings' => [
        'warning' => t('Warning message'),
      ],
      '#weight' => -201,
    ];
  }
  elseif (in_array($entity
    ->getEntityTypeId(), $delete_entity_types)) {

    // Even if this is not on the UI, sites can define additional form classes
    // where the delete message can be shown.
    $form_classes = $config
      ->get('delete_warning_form_classes') ?: [
      'Drupal\\Core\\Entity\\ContentEntityDeleteForm',
    ];
    $is_delete_form = FALSE;
    foreach ($form_classes as $class) {
      if ($form_object instanceof $class) {
        $is_delete_form = TRUE;
        break;
      }
    }
    if ($is_delete_form) {
      $form['entity_usage_delete_warning'] = [
        '#theme' => 'status_messages',
        '#message_list' => [
          'warning' => [
            t('There are <a href="@usage_url" target="_blank">recorded usages</a> of this entity.', [
              '@usage_url' => Url::fromRoute('entity_usage.usage_list', [
                'entity_type' => $entity
                  ->getEntityTypeId(),
                'entity_id' => $entity
                  ->id(),
              ])
                ->toString(),
            ]),
          ],
        ],
        '#status_headings' => [
          'warning' => t('Warning message'),
        ],
        '#weight' => -201,
      ];
    }
  }
}