Skip to content

Instantly share code, notes, and snippets.

@andypost
Last active March 16, 2016 19:41
Show Gist options
  • Save andypost/ab55208a29ee6300d0a4 to your computer and use it in GitHub Desktop.
Save andypost/ab55208a29ee6300d0a4 to your computer and use it in GitHub Desktop.
usage `$reverter = \Drupal::service('config_update.config_update'); $reverter->revert('user_role', 'administrator');` in hook_update_N()
<?php
/**
* @file
* Contains \Drupal\custom_utility\ConfigUpdater.
*/
namespace Drupal\custom_utility;
use Drupal\config\StorageReplaceDataWrapper;
use Drupal\config_update\ConfigListInterface;
use Drupal\config_update\ConfigRevertInterface;
use Drupal\Core\Config\ConfigImporter;
use Drupal\Core\Config\ConfigImporterException;
use Drupal\Core\Config\ConfigManagerInterface;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\InstallStorage;
use Drupal\Core\Config\StorageComparer;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Extension\ModuleInstallerInterface;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Provides method related to config reverting and importing.
*/
class ConfigUpdater implements ConfigUpdaterInterface {
use StringTranslationTrait;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The config storage.
*
* @var \Drupal\Core\Config\StorageInterface
*/
protected $configStorage;
/**
* The renderer service.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* The event dispatcher.
*
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* The configuration manager.
*
* @var \Drupal\Core\Config\ConfigManagerInterface;
*/
protected $configManager;
/**
* The database lock object.
*
* @var \Drupal\Core\Lock\LockBackendInterface
*/
protected $lock;
/**
* The typed config manager.
*
* @var \Drupal\Core\Config\TypedConfigManagerInterface
*/
protected $typedConfigManager;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The theme handler.
*
* @var \Drupal\Core\Extension\ThemeHandlerInterface
*/
protected $themeHandler;
/**
* The module installer.
*
* @var \Drupal\Core\Extension\ModuleInstallerInterface
*/
protected $moduleInstaller;
/**
* The config reverter.
*
* @var \Drupal\config_update\ConfigRevertInterface
*/
protected $reverter;
/**
* The config list service.
*
* @var \Drupal\config_update\ConfigListInterface
*/
protected $configList;
/**
* Array of configs types and data.
*
* @var array
*/
protected $importList = [];
/**
* Array of simple configs names and actions.
*
* @var array
*/
protected $importSimpleList = [];
/**
* Constructs a new ConfigSingleImportForm.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Config\StorageInterface $config_storage
* The config storage.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher used to notify subscribers of config import events.
* @param \Drupal\Core\Config\ConfigManagerInterface $config_manager
* The configuration manager.
* @param \Drupal\Core\Lock\LockBackendInterface $lock
* The lock backend to ensure multiple imports
* do not occur at the same time.
* @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
* The typed configuration manager.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\Extension\ModuleInstallerInterface $module_installer
* The module installer.
* @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
* The theme handler.
* @param \Drupal\config_update\ConfigRevertInterface $reverter
* The reverter service.
* @param \Drupal\config_update\ConfigListInterface $config_list
* The config list service.
*/
public function __construct(
EntityTypeManagerInterface $entity_type_manager,
StorageInterface $config_storage,
RendererInterface $renderer,
EventDispatcherInterface $event_dispatcher,
ConfigManagerInterface $config_manager,
LockBackendInterface $lock,
TypedConfigManagerInterface $typed_config,
ModuleHandlerInterface $module_handler,
ModuleInstallerInterface $module_installer,
ThemeHandlerInterface $theme_handler,
ConfigRevertInterface $reverter,
ConfigListInterface $config_list
) {
$this->entityTypeManager = $entity_type_manager;
$this->configStorage = $config_storage;
$this->renderer = $renderer;
// Services necessary for \Drupal\Core\Config\ConfigImporter.
$this->eventDispatcher = $event_dispatcher;
$this->configManager = $config_manager;
$this->lock = $lock;
$this->typedConfigManager = $typed_config;
$this->moduleHandler = $module_handler;
$this->moduleInstaller = $module_installer;
$this->themeHandler = $theme_handler;
$this->reverter = $reverter;
$this->configList = $config_list;
}
/**
* {@inheritdoc}
*/
public function update() {
$modules = [
'project_module1',
'project_profile',
];
// Get install and optional configs from modules list.
foreach ([InstallStorage::CONFIG_INSTALL_DIRECTORY, InstallStorage::CONFIG_OPTIONAL_DIRECTORY] as $dir) {
foreach ($modules as $module) {
$install_path = drupal_get_path('module', $module) . '/' . $dir;
$module_storage = new FileStorage($install_path, StorageInterface::DEFAULT_COLLECTION);
$module_config = $module_storage->listAll();
foreach ($module_config as $name) {
$type = $this->configList->getTypeNameByConfigName($name);
if (!$type) {
// Simple configs would be processed by config_update service.
$this->importSimpleList[] = [
'action' => $this->configStorage->exists($name) ? 'revert' : 'import',
'id' => $name,
];
}
else {
$config = $this->reverter->getFromExtension('', $name);
// Get active config for replace uuid field for existing config.
if ($active_config = $this->reverter->getFromActive('', $name)) {
if (isset($active_config['uuid'])) {
$config['uuid'] = $active_config['uuid'];
}
if (isset($active_config['settings']['default_image']['uuid'])) {
$config['settings']['default_image']['uuid'] = $active_config['settings']['default_image']['uuid'];
}
}
$this->importList[] = [
'type' => $type,
'data' => $config,
];
}
}
}
}
$this->processImport();
$this->processSimpleImport();
}
/**
* Helper function for import or revert configs.
*/
protected function processImport() {
$source_storage = new StorageReplaceDataWrapper($this->configStorage);
foreach ($this->importList as $conf) {
$type = $conf['type'];
$data = $conf['data'];
$definition = $this->entityTypeManager->getDefinition($type);
$id_key = $definition->getKey('id');
// If an entity ID was not specified, continue.
if (!isset($data[$id_key])) {
continue;
}
$config_name = $definition->getConfigPrefix() . '.' . $data[$id_key];
$source_storage->replaceData($config_name, $data);
}
$storage_comparer = new StorageComparer(
$source_storage,
$this->configStorage,
$this->configManager
);
if ($storage_comparer->createChangelist()->hasChanges()) {
$config_importer = new ConfigImporter(
$storage_comparer,
$this->eventDispatcher,
$this->configManager,
$this->lock,
$this->typedConfigManager,
$this->moduleHandler,
$this->moduleInstaller,
$this->themeHandler,
$this->getStringTranslation()
);
try {
$config_importer->validate();
$config_importer->import();
$this->importList = [];
}
catch (ConfigImporterException $e) {
watchdog_exception('error', $e);
}
}
}
/**
* Helper function for import or revert simple configs.
*/
protected function processSimpleImport() {
foreach ($this->importSimpleList as $config) {
$this->reverter->{$config['action']}('system.simple', $config['id']);
}
$this->importSimpleList = [];
}
}
@andypost
Copy link
Author

and services.yml file

  custom_utility.config_updater:
    class: Drupal\custom_utility\ConfigUpdater
    arguments: ['@entity_type.manager', '@config.storage', '@renderer', '@event_dispatcher', '@config.manager', '@lock.persistent', '@config.typed', '@module_handler', '@module_installer', '@theme_handler', '@config_update.config_update', '@config_update.config_list']

@andypost
Copy link
Author

\Drupal::service('customutility.config_updater')->update();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment