View source
<?php
namespace Drupal\config_import;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\Config\ConfigImporterException;
use Drupal\Core\Config\ConfigManagerInterface;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\Config\TypedConfigManager;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\ProxyClass\Extension\ModuleInstaller;
use Drupal\Core\Extension\ThemeHandler;
use Drupal\Core\StringTranslation\TranslationManager;
use Drupal\Core\File\FileSystem;
use Drupal\Core\Config\ConfigException;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\StorageComparer;
use Drupal\Core\Config\ConfigImporter;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Component\FileCache\FileCacheFactory;
use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ConfigImporterService implements ConfigImporterServiceInterface {
protected $uuid;
protected $configStorage;
protected $configManager;
protected $eventDispatcher;
protected $lock;
protected $configTyped;
protected $moduleHandler;
protected $moduleInstaller;
protected $themeHandler;
protected $translationManager;
protected $fileSystem;
protected $directory = '';
private $fileCacheConfig = [];
public function __construct(UuidInterface $uuid, CachedStorage $config_storage, ConfigManagerInterface $config_manager, ContainerAwareEventDispatcher $event_dispatcher, LockBackendInterface $lock, TypedConfigManager $config_typed, ModuleHandler $module_handler, ModuleInstaller $module_installer, ThemeHandler $theme_handler, TranslationManager $translation_manager, FileSystem $file_system) {
$this->uuid = $uuid;
$this->configStorage = $config_storage;
$this->configManager = $config_manager;
$this->eventDispatcher = $event_dispatcher;
$this->lock = $lock;
$this->configTyped = $config_typed;
$this->moduleHandler = $module_handler;
$this->moduleInstaller = $module_installer;
$this->themeHandler = $theme_handler;
$this->translationManager = $translation_manager;
$this->fileSystem = $file_system;
$this->fileCacheConfig = FileCacheFactory::getConfiguration();
FileCacheFactory::setConfiguration([
FileCacheFactory::DISABLE_CACHE => TRUE,
]);
$this
->setDirectory(\Drupal\Core\Site\Settings::get('config_sync_directory'));
}
public function __destruct() {
FileCacheFactory::setConfiguration($this->fileCacheConfig);
}
public static function create(ContainerInterface $container) {
return new static($container
->get('uuid'), $container
->get('config.storage'), $container
->get('config.manager'), $container
->get('event_dispatcher'), $container
->get('lock'), $container
->get('config.typed'), $container
->get('module_handler'), $container
->get('module_installer'), $container
->get('theme_handler'), $container
->get('string_translation'), $container
->get('file_system'));
}
public function setDirectory($directory) {
if (!is_dir($directory)) {
throw new \InvalidArgumentException($directory . ' - is not valid path or type of directory with configurations.');
}
$this->directory = $directory;
}
public function getDirectory() {
return $this->directory;
}
public function importConfigs(array $configs) {
$tmp_dir = (defined('MAINTENANCE_MODE') ? '/tmp' : 'temporary:/') . '/confi_' . $this->uuid
->generate();
if (!$this->fileSystem
->mkdir($tmp_dir)) {
throw new ConfigImporterException('Failed to create temporary directory: ' . $tmp_dir);
}
$tmp_storage = new FileStorage($tmp_dir);
$this
->export($tmp_storage);
foreach ($configs as $config) {
$file = "{$this->directory}/{$config}.yml";
if (file_exists($file)) {
file_unmanaged_copy($file, $tmp_dir, FileSystemInterface::EXISTS_REPLACE);
}
else {
$tmp_storage
->delete($config);
$this->configStorage
->delete($config);
}
}
$this
->filter($tmp_storage);
$this
->import($tmp_storage);
}
public function exportConfigs(array $configs) {
$storage = new FileStorage($this->directory);
foreach ($configs as $config) {
$storage
->write($config, $this->configStorage
->read($config));
}
}
protected function filter(FileStorage $storage) {
$configs = [];
$this->moduleHandler
->alter('config_import_configs', $configs);
foreach ($configs as $config) {
$storage
->delete($config);
}
}
protected function export(FileStorage $storage) {
foreach ($this->configStorage
->listAll() as $config) {
$storage
->write($config, $this->configStorage
->read($config));
}
}
protected function import(FileStorage $storage) {
$storage_comparer = new StorageComparer($storage, $this->configStorage, $this->configManager);
if (!$storage_comparer
->createChangelist()
->hasChanges()) {
return;
}
$config_importer = new ConfigImporter($storage_comparer, $this->eventDispatcher, $this->configManager, $this->lock, $this->configTyped, $this->moduleHandler, $this->moduleInstaller, $this->themeHandler, $this->translationManager);
try {
$config_importer
->validate()
->import();
} catch (ConfigException $e) {
throw new ConfigImporterException(implode("\n", $config_importer
->getErrors()));
}
}
}