Same filename and directory in other branches
- 8.9.x core/lib/Drupal/Core/Config/Entity/ConfigEntityUpdater.php
- 9 core/lib/Drupal/Core/Config/Entity/ConfigEntityUpdater.php
Namespace
Drupal\Core\Config\Entity
File
core/lib/Drupal/Core/Config/Entity/ConfigEntityUpdater.php
View source
<?php
namespace Drupal\Core\Config\Entity;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\Core\Utility\Error;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ConfigEntityUpdater implements ContainerInjectionInterface {
const SANDBOX_KEY = 'config_entity_updater';
protected $entityTypeManager;
protected $batchSize;
public function __construct(EntityTypeManagerInterface $entity_type_manager, $batch_size) {
$this->entityTypeManager = $entity_type_manager;
$this->batchSize = $batch_size;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'), $container
->get('settings')
->get('entity_update_batch_size', 50));
}
public function update(array &$sandbox, $entity_type_id, callable $callback = NULL, bool $continue_on_error = FALSE) {
$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']);
$sandbox[self::SANDBOX_KEY]['failed_entity_ids'] = [];
}
if ($callback === NULL) {
$callback = function ($entity) {
$original_dependencies = $entity
->getDependencies();
return $original_dependencies !== $entity
->calculateDependencies()
->getDependencies();
};
}
$entities = $storage
->loadMultiple(array_splice($sandbox[self::SANDBOX_KEY]['entities'], 0, $this->batchSize));
foreach ($entities as $entity) {
try {
if ($continue_on_error) {
@$this
->doOne($entity, $callback);
}
else {
$this
->doOne($entity, $callback);
}
} catch (\Throwable $throwable) {
if (!$continue_on_error) {
throw $throwable;
}
$context['%view'] = $entity
->id();
$context['%entity_type'] = $entity_type_id;
$context += Error::decodeException($throwable);
\Drupal::logger('update')
->error('Unable to update %entity_type %view due to error @message %function (line %line of %file). <pre>@backtrace_string</pre>', $context);
$sandbox[self::SANDBOX_KEY]['failed_entity_ids'][] = $entity
->id();
}
}
$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'];
if (!empty($sandbox[self::SANDBOX_KEY]['failed_entity_ids'])) {
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id);
if (\Drupal::moduleHandler()
->moduleExists('dblog')) {
return new TranslatableMarkup('Updates failed for the entity type %entity_type, for %entity_ids. <a href=":url">Check the logs</a>.', [
'%entity_type' => $entity_type
->getLabel(),
'%entity_ids' => implode(', ', $sandbox[self::SANDBOX_KEY]['failed_entity_ids']),
':url' => Url::fromRoute('dblog.overview')
->toString(),
]);
}
else {
return new TranslatableMarkup("Updates failed for the entity type %entity_type, for %entity_ids. Check the logs.", [
'%entity_type' => $entity_type
->getLabel(),
'%entity_ids' => implode(', ', $sandbox[self::SANDBOX_KEY]['failed_entity_ids']),
]);
}
}
}
protected function doOne(ConfigEntityInterface $entity, callable $callback) {
if (call_user_func($callback, $entity)) {
$entity
->trustData();
$entity
->save();
}
}
}
Classes