Same name and namespace in other branches
  1. 8.9.x core/modules/views/src/EventSubscriber/ViewsEntitySchemaSubscriber.php \Drupal\views\EventSubscriber\ViewsEntitySchemaSubscriber::onEntityTypeUpdate()
  2. 9 core/modules/views/src/EventSubscriber/ViewsEntitySchemaSubscriber.php \Drupal\views\EventSubscriber\ViewsEntitySchemaSubscriber::onEntityTypeUpdate()

Overrides EntityTypeEventSubscriberTrait::onEntityTypeUpdate

File

core/modules/views/src/EventSubscriber/ViewsEntitySchemaSubscriber.php, line 116

Class

ViewsEntitySchemaSubscriber
Reacts to changes on entity types to update all views entities.

Namespace

Drupal\views\EventSubscriber

Code

public function onEntityTypeUpdate(EntityTypeInterface $entity_type, EntityTypeInterface $original) {
  $changes = [];

  // We implement a specific logic for table updates, which is bound to the
  // default sql content entity storage.
  if (!$this->entityTypeManager
    ->getStorage($entity_type
    ->id()) instanceof SqlContentEntityStorage) {
    return;
  }
  if ($entity_type
    ->getBaseTable() != $original
    ->getBaseTable()) {
    $changes[] = static::BASE_TABLE_RENAME;
  }
  $revision_add = $entity_type
    ->isRevisionable() && !$original
    ->isRevisionable();
  $revision_remove = !$entity_type
    ->isRevisionable() && $original
    ->isRevisionable();
  $translation_add = $entity_type
    ->isTranslatable() && !$original
    ->isTranslatable();
  $translation_remove = !$entity_type
    ->isTranslatable() && $original
    ->isTranslatable();
  if ($revision_add) {
    $changes[] = static::REVISION_TABLE_ADDITION;
  }
  elseif ($revision_remove) {
    $changes[] = static::REVISION_TABLE_REMOVAL;
  }
  elseif ($entity_type
    ->isRevisionable() && $entity_type
    ->getRevisionTable() != $original
    ->getRevisionTable()) {
    $changes[] = static::REVISION_TABLE_RENAME;
  }
  if ($translation_add) {
    $changes[] = static::DATA_TABLE_ADDITION;
  }
  elseif ($translation_remove) {
    $changes[] = static::DATA_TABLE_REMOVAL;
  }
  elseif ($entity_type
    ->isTranslatable() && $entity_type
    ->getDataTable() != $original
    ->getDataTable()) {
    $changes[] = static::DATA_TABLE_RENAME;
  }
  if ($entity_type
    ->isRevisionable() && $entity_type
    ->isTranslatable()) {
    if ($revision_add || $translation_add) {
      $changes[] = static::REVISION_DATA_TABLE_ADDITION;
    }
    elseif ($entity_type
      ->getRevisionDataTable() != $original
      ->getRevisionDataTable()) {
      $changes[] = static::REVISION_DATA_TABLE_RENAME;
    }
  }
  elseif ($original
    ->isRevisionable() && $original
    ->isTranslatable() && ($revision_remove || $translation_remove)) {
    $changes[] = static::REVISION_DATA_TABLE_REMOVAL;
  }

  // Stop here if no changes are needed.
  if (empty($changes)) {
    return;
  }

  /** @var \Drupal\views\Entity\View[] $all_views */
  $all_views = $this->entityTypeManager
    ->getStorage('view')
    ->loadMultiple(NULL);
  foreach ($changes as $change) {
    switch ($change) {
      case static::BASE_TABLE_RENAME:
        $this
          ->baseTableRename($all_views, $entity_type
          ->id(), $original
          ->getBaseTable(), $entity_type
          ->getBaseTable());
        break;
      case static::DATA_TABLE_RENAME:
        $this
          ->dataTableRename($all_views, $entity_type
          ->id(), $original
          ->getDataTable(), $entity_type
          ->getDataTable());
        break;
      case static::DATA_TABLE_ADDITION:
        $this
          ->dataTableAddition($all_views, $entity_type, $entity_type
          ->getDataTable(), $entity_type
          ->getBaseTable());
        break;
      case static::DATA_TABLE_REMOVAL:
        $this
          ->dataTableRemoval($all_views, $entity_type
          ->id(), $original
          ->getDataTable(), $entity_type
          ->getBaseTable());
        break;
      case static::REVISION_TABLE_RENAME:
        $this
          ->baseTableRename($all_views, $entity_type
          ->id(), $original
          ->getRevisionTable(), $entity_type
          ->getRevisionTable());
        break;
      case static::REVISION_TABLE_ADDITION:

        // If we add revision support we don't have to do anything.
        break;
      case static::REVISION_TABLE_REMOVAL:
        $this
          ->revisionRemoval($all_views, $original);
        break;
      case static::REVISION_DATA_TABLE_RENAME:
        $this
          ->dataTableRename($all_views, $entity_type
          ->id(), $original
          ->getRevisionDataTable(), $entity_type
          ->getRevisionDataTable());
        break;
      case static::REVISION_DATA_TABLE_ADDITION:
        $this
          ->dataTableAddition($all_views, $entity_type, $entity_type
          ->getRevisionDataTable(), $entity_type
          ->getRevisionTable());
        break;
      case static::REVISION_DATA_TABLE_REMOVAL:
        $this
          ->dataTableRemoval($all_views, $entity_type
          ->id(), $original
          ->getRevisionDataTable(), $entity_type
          ->getRevisionTable());
        break;
    }
  }
  foreach ($this->viewsToSave as $view) {
    try {

      // All changes done to the views here can be trusted and this might be
      // called during updates, when it is not safe to rely on configuration
      // containing valid schema. Trust the data and disable schema validation
      // and casting.
      $view
        ->trustData()
        ->save();
    } catch (\Exception $e) {

      // In case the view could not be saved, log an error message that the
      // view needs to be updated manually instead of failing the entire
      // entity update process.
      $this->logger
        ->critical("The %view_id view could not be updated automatically while processing an entity schema update for the %entity_type_id entity type.", [
        '%view_id' => $view
          ->id(),
        '%entity_type_id' => $entity_type
          ->id(),
      ]);
    }
  }
  $this->viewsToSave = [];
}