View source
<?php
namespace Drupal\commerce\Config;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Config\ExtensionInstallStorage;
use Drupal\Core\Config\InstallStorage;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
class ConfigUpdater implements ConfigUpdaterInterface {
use StringTranslationTrait;
protected $entityTypeManager;
protected $activeConfigStorage;
protected $extensionConfigStorage;
protected $extensionOptionalConfigStorage;
protected $configFactory;
protected $typesByPrefix = [];
public function __construct(EntityTypeManagerInterface $entity_type_manager, StorageInterface $active_config_storage, ConfigFactoryInterface $config_factory) {
$this->entityTypeManager = $entity_type_manager;
$this->activeConfigStorage = $active_config_storage;
$this->extensionConfigStorage = new ExtensionInstallStorage($active_config_storage, InstallStorage::CONFIG_INSTALL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION, TRUE, \Drupal::installProfile());
$this->extensionOptionalConfigStorage = new ExtensionInstallStorage($active_config_storage, InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION, TRUE, \Drupal::installProfile());
$this->configFactory = $config_factory;
foreach ($this->entityTypeManager
->getDefinitions() as $entity_type => $definition) {
if ($definition
->entityClassImplements(ConfigEntityInterface::class)) {
$prefix = $definition
->getConfigPrefix();
$this->typesByPrefix[$prefix] = $entity_type;
}
}
}
public function import(array $config_names) {
$succeeded = [];
$failed = [];
foreach ($config_names as $config_name) {
$config_data = $this
->loadFromExtension($config_name);
if (!$config_data) {
$failed[$config_name] = $this
->t('@config does not exist in extension storage', [
'@config' => $config_name,
]);
continue;
}
if ($this
->loadFromActive($config_name)) {
$failed[$config_name] = $this
->t('@config already exists, use revert to update', [
'@config' => $config_name,
]);
continue;
}
$config_type = $this
->getConfigType($config_name);
if ($config_type == 'system.simple') {
$this->configFactory
->getEditable($config_name)
->setData($config_data)
->save();
}
else {
$entity_storage = $this->entityTypeManager
->getStorage($config_type);
$entity = $entity_storage
->createFromStorageRecord($config_data);
$entity
->save();
}
$succeeded[$config_name] = $this
->t('@config was successfully imported', [
'@config' => $config_name,
]);
}
return new ConfigUpdateResult($succeeded, $failed);
}
public function revert(array $config_names, $skip_modified = TRUE) {
$succeeded = [];
$failed = [];
foreach ($config_names as $config_name) {
$config_data = $this
->loadFromExtension($config_name);
if (!$config_data) {
$failed[$config_name] = $this
->t('@config does not exist in extension storage', [
'@config' => $config_name,
]);
continue;
}
$active_config_data = $this
->loadFromActive($config_name);
if (!$active_config_data) {
$succeeded[$config_name] = $this
->t('Skipped: @config does not exist in active storage', [
'@config' => $config_name,
]);
continue;
}
if ($this
->isModified($active_config_data) && $skip_modified) {
$succeeded[$config_name] = $this
->t('Skipped: @config was not reverted because it was modified by the user', [
'@config' => $config_name,
]);
continue;
}
$config_type = $this
->getConfigType($config_name);
if ($config_type == 'system.simple') {
$this->configFactory
->getEditable($config_name)
->setData($config_data)
->save();
}
else {
$entity_type = $this->entityTypeManager
->getDefinition($config_type);
$id = substr($config_name, strlen($entity_type
->getConfigPrefix()) + 1);
$entity_storage = $this->entityTypeManager
->getStorage($config_type);
$entity = $entity_storage
->load($id);
$uuid = $entity
->uuid();
$entity = $entity_storage
->updateFromStorageRecord($entity, $config_data);
$entity
->set('uuid', $uuid);
$entity
->save();
}
$succeeded[$config_name] = $this
->t('@config was successfully reverted', [
'@config' => $config_name,
]);
}
return new ConfigUpdateResult($succeeded, $failed);
}
public function delete(array $config_names) {
$succeeded = [];
$failed = [];
foreach ($config_names as $config_name) {
if (!$this
->loadFromActive($config_name)) {
$succeeded[$config_name] = $this
->t('Skipped: @config does not exist in active storage', [
'@config' => $config_name,
]);
continue;
}
$config_type = $this
->getConfigType($config_name);
if ($config_type == 'system.simple') {
$this->configFactory
->getEditable($config_name)
->delete();
}
else {
$entity_type = $this->entityTypeManager
->getDefinition($config_type);
$id = substr($config_name, strlen($entity_type
->getConfigPrefix()) + 1);
$entity_storage = $this->entityTypeManager
->getStorage($config_type);
$entity = $entity_storage
->load($id);
$entity_storage
->delete([
$entity,
]);
}
$succeeded[$config_name] = $this
->t('@config was successfully deleted', [
'@config' => $config_name,
]);
}
return new ConfigUpdateResult($succeeded, $failed);
}
public function loadFromActive($config_name) {
return $this->activeConfigStorage
->read($config_name);
}
public function loadFromExtension($config_name) {
$data = $this->extensionConfigStorage
->read($config_name);
if (!$data) {
$data = $this->extensionOptionalConfigStorage
->read($config_name);
}
return $data;
}
public function isModified(array $config) {
$original_hash = $config['_core']['default_config_hash'];
unset($config['uuid']);
unset($config['_core']);
$current_hash = Crypt::hashBase64(serialize($config));
return $original_hash !== $current_hash;
}
protected function getConfigType($config_name) {
foreach ($this->typesByPrefix as $prefix => $config_type) {
if (strpos($config_name, $prefix) === 0) {
return $config_type;
}
}
return NULL;
}
}