function ViewsEntitySchemaSubscriber::onEntityTypeUpdate

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

Overrides EntityTypeEventSubscriberTrait::onEntityTypeUpdate

File

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

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;
        }
    }
    // Filter the list of views that needs to be updated.
    $views_to_update = array_filter($all_views, function (ViewEntityInterface $view) {
        return $view->get('_updated') === TRUE;
    });
    foreach ($views_to_update 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->set('_updated', NULL);
            $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(),
            ]);
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.