<?php
use Drupal\Core\Config\Config;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\NullStorage;
use Drupal\Core\Config\StorageInterface;
const CONFIG_IMPORT_LOCK = 'config_import';
function config_install_default_config($type, $name) {
$config_dir = drupal_get_path($type, $name) . '/config';
if (is_dir($config_dir)) {
$source_storage = new FileStorage($config_dir);
$target_storage = drupal_container()
->get('config.storage');
foreach (config_get_module_config_entities($name) as $entity_type => $entity_info) {
$manifest_config = config('manifest.' . $entity_info['config_prefix']);
$manifest_data = array();
foreach ($source_storage
->listAll($entity_info['config_prefix']) as $config_name) {
list(, , $id) = explode('.', $config_name);
$manifest_data[$id]['name'] = $config_name;
}
$manifest_config
->setData($manifest_data)
->save();
}
$config_changes = array(
'delete' => array(),
'create' => array(),
'change' => array(),
);
$config_changes['create'] = $source_storage
->listAll();
if (empty($config_changes['create'])) {
return;
}
$remaining_changes = config_import_invoke_owner($config_changes, $source_storage, $target_storage);
config_sync_changes($remaining_changes, $source_storage, $target_storage);
}
}
function config_uninstall_default_config($type, $name) {
$storage = drupal_container()
->get('config.storage');
$config_names = $storage
->listAll($name . '.');
foreach ($config_names as $config_name) {
config($config_name)
->delete();
}
foreach (config_get_module_config_entities($name) as $entity_type) {
config('manifest.' . $entity_info['config_prefix'])
->delete();
}
}
function config_get_storage_names_with_prefix($prefix = '') {
return drupal_container()
->get('config.storage')
->listAll($prefix);
}
function config($name) {
return drupal_container()
->get('config.factory')
->get($name)
->load();
}
function config_sync_get_changes(StorageInterface $source_storage, StorageInterface $target_storage) {
$source_config_data = array();
$target_config_data = array();
foreach ($source_storage
->listAll('manifest') as $name) {
if ($source_manifest_data = $source_storage
->read($name)) {
$source_config_data = array_merge($source_config_data, $source_manifest_data);
}
if ($target_manifest_data = $target_storage
->read($name)) {
$target_config_data = array_merge($target_config_data, $target_manifest_data);
}
}
$config_changes = array(
'create' => array(),
'change' => array(),
'delete' => array(),
);
foreach (array_diff_assoc($target_config_data, $source_config_data) as $name => $value) {
$config_changes['delete'][] = $value['name'];
}
foreach (array_diff_assoc($source_config_data, $target_config_data) as $name => $value) {
$config_changes['create'][] = $value['name'];
}
foreach (array_intersect($source_storage
->listAll(), $target_storage
->listAll()) as $name) {
if (substr($name, 0, 9) != 'manifest.') {
$source_config_data = $source_storage
->read($name);
$target_config_data = $target_storage
->read($name);
if ($source_config_data !== $target_config_data) {
$config_changes['change'][] = $name;
}
}
}
if (empty($config_changes['create']) && empty($config_changes['change']) && empty($config_changes['delete'])) {
return FALSE;
}
return $config_changes;
}
function config_sync_changes(array $config_changes, StorageInterface $source_storage, StorageInterface $target_storage) {
foreach (array(
'delete',
'create',
'change',
) as $op) {
foreach ($config_changes[$op] as $name) {
if ($op == 'delete') {
$target_storage
->delete($name);
}
else {
$data = $source_storage
->read($name);
$target_storage
->write($name, $data);
}
}
}
}
function config_import() {
$source_storage = drupal_container()
->get('config.storage.staging');
$target_storage = drupal_container()
->get('config.storage');
$config_changes = config_sync_get_changes($source_storage, $target_storage);
if (empty($config_changes)) {
return;
}
if (!lock()
->acquire(CONFIG_IMPORT_LOCK)) {
return FALSE;
}
$success = TRUE;
try {
$remaining_changes = config_import_invoke_owner($config_changes, $source_storage, $target_storage);
config_sync_changes($remaining_changes, $source_storage, $target_storage);
} catch (ConfigException $e) {
watchdog_exception('config_import', $e);
$success = FALSE;
}
lock()
->release(CONFIG_IMPORT_LOCK);
return $success;
}
function config_import_invoke_owner(array $config_changes, StorageInterface $source_storage, StorageInterface $target_storage) {
foreach (array(
'delete',
'create',
'change',
) as $op) {
foreach ($config_changes[$op] as $key => $name) {
$module = strtok($name, '.');
$handled_by_module = FALSE;
if (module_exists($module) && module_hook($module, 'config_import_' . $op)) {
$old_config = new Config($name, $target_storage);
$old_config
->load();
$data = $source_storage
->read($name);
$new_config = new Config($name, $target_storage);
if ($data !== FALSE) {
$new_config
->setData($data);
}
$handled_by_module = module_invoke($module, 'config_import_' . $op, $name, $new_config, $old_config);
}
if (!empty($handled_by_module)) {
unset($config_changes[$op][$key]);
}
}
}
return $config_changes;
}
function config_get_module_config_entities($module) {
$info = entity_get_info();
return array_filter($info, function ($entity_info) use ($module) {
return $entity_info['module'] == $module && is_subclass_of($entity_info['class'], 'Drupal\\Core\\Config\\Entity\\ConfigEntityInterface');
});
}