You are here

public function ConfigEntityUpdater::update in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Config/Entity/ConfigEntityUpdater.php \Drupal\Core\Config\Entity\ConfigEntityUpdater::update()

Updates configuration entities as part of a Drupal update.

@api

Parameters

array $sandbox: Stores information for batch updates.

string $entity_type_id: The configuration entity type ID. For example, 'view' or 'vocabulary'. The calling code should ensure that the entity type exists beforehand (i.e., by checking that the entity type is defined or that the module that provides it is installed).

callable $callback: (optional) A callback to determine if a configuration entity should be saved. The callback will be passed each entity of the provided type that exists. The callback should not save an entity itself. Return TRUE to save an entity. The callback can make changes to an entity. Note that all changes should comply with schema as an entity's data will not be validated against schema on save to avoid unexpected errors. If a callback is not provided, the default behavior is to update the dependencies if required.

Throws

\InvalidArgumentException Thrown when the provided entity type ID is not a configuration entity type.

\RuntimeException Thrown when used twice in the same update function for different entity types. This method should only be called once per update function.

See also

hook_post_update_NAME()

File

core/lib/Drupal/Core/Config/Entity/ConfigEntityUpdater.php, line 100

Class

ConfigEntityUpdater
A utility class to make updating configuration entities simple.

Namespace

Drupal\Core\Config\Entity

Code

public function update(array &$sandbox, $entity_type_id, callable $callback = NULL) {
  $storage = $this->entityTypeManager
    ->getStorage($entity_type_id);
  if (isset($sandbox[self::SANDBOX_KEY]) && $sandbox[self::SANDBOX_KEY]['entity_type'] !== $entity_type_id) {
    throw new \RuntimeException('Updating multiple entity types in the same update function is not supported');
  }
  if (!isset($sandbox[self::SANDBOX_KEY])) {
    $entity_type = $this->entityTypeManager
      ->getDefinition($entity_type_id);
    if (!$entity_type instanceof ConfigEntityTypeInterface) {
      throw new \InvalidArgumentException("The provided entity type ID '{$entity_type_id}' is not a configuration entity type");
    }
    $sandbox[self::SANDBOX_KEY]['entity_type'] = $entity_type_id;
    $sandbox[self::SANDBOX_KEY]['entities'] = $storage
      ->getQuery()
      ->accessCheck(FALSE)
      ->execute();
    $sandbox[self::SANDBOX_KEY]['count'] = count($sandbox[self::SANDBOX_KEY]['entities']);
  }

  // The default behavior is to fix dependencies.
  if ($callback === NULL) {
    $callback = function ($entity) {

      /** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $entity */
      $original_dependencies = $entity
        ->getDependencies();
      return $original_dependencies !== $entity
        ->calculateDependencies()
        ->getDependencies();
    };
  }

  /** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $entity */
  $entities = $storage
    ->loadMultiple(array_splice($sandbox[self::SANDBOX_KEY]['entities'], 0, $this->batchSize));
  foreach ($entities as $entity) {
    if (call_user_func($callback, $entity)) {
      $entity
        ->trustData();
      $entity
        ->save();
    }
  }
  $sandbox['#finished'] = empty($sandbox[self::SANDBOX_KEY]['entities']) ? 1 : ($sandbox[self::SANDBOX_KEY]['count'] - count($sandbox[self::SANDBOX_KEY]['entities'])) / $sandbox[self::SANDBOX_KEY]['count'];
}