View source
<?php
namespace Drupal\config_rewrite;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Logger\LoggerChannelInterface;
use Symfony\Component\Yaml\Yaml;
use Drupal\Core\File\FileSystemInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\config_rewrite\Exception\NonexistentInitialConfigException;
class ConfigRewriter implements ConfigRewriterInterface {
protected $configFactory;
protected $languageConfigFactoryOverride;
protected $moduleHandler;
protected $logger;
protected $fileSystem;
public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, LoggerChannelInterface $logger, FileSystemInterface $file_system, $language_config_factory_override) {
$this->configFactory = $config_factory;
$this->moduleHandler = $module_handler;
$this->logger = $logger;
$this->fileSystem = $file_system;
$this->languageConfigFactoryOverride = $language_config_factory_override;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('file_system'));
}
public function rewriteModuleConfig($module) {
$extension = $this->moduleHandler
->getModule($module);
$dir_base = $extension
->getPath() . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'rewrite';
$languages = \Drupal::languageManager()
->getLanguages();
$this
->rewriteDirectoryConfig($extension, $dir_base);
foreach ($languages as $langcode => $language) {
$rewrite_dir = $dir_base . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR . $langcode;
$this
->rewriteDirectoryConfig($extension, $rewrite_dir, $langcode);
}
}
protected function rewriteDirectoryConfig($extension, $rewrite_dir, $langcode = NULL) {
if ($langcode && !$this->languageConfigFactoryOverride) {
return;
}
if (file_exists($rewrite_dir) && ($files = $this
->fileScanDirectory($rewrite_dir, '/^.*\\.yml$/i', [
'recurse' => FALSE,
]))) {
foreach ($files as $file) {
$rewrite = Yaml::parse(file_get_contents($rewrite_dir . DIRECTORY_SEPARATOR . $file->name . '.yml'));
if ($langcode) {
$config = $this->languageConfigFactoryOverride
->getOverride($langcode, $file->name);
$original_data = $config
->get();
$rewrite = $this
->rewriteConfig($original_data, $rewrite, $file->name, $extension
->getName());
}
else {
$config = $this->configFactory
->getEditable($file->name);
$original_data = $config
->getRawData();
$rewrite = $this
->rewriteConfig($original_data, $rewrite, $file->name, $extension
->getName());
}
if (isset($rewrite['config_rewrite'])) {
unset($rewrite['config_rewrite']);
}
if (isset($rewrite['config_rewrite_uuids'])) {
unset($rewrite['config_rewrite_uuids']);
}
else {
foreach ([
'_core',
'uuid',
] as $key) {
if (isset($original_data[$key])) {
$rewrite[$key] = $original_data[$key];
}
}
}
$result = $config
->setData($rewrite)
->save() ? 'rewritten' : 'not rewritten';
$log = $langcode ? '@config (@langcode) @result by @module' : '@config @result by @module';
$this->logger
->notice($log, [
'@config' => $file->name,
'@result' => $result,
'@module' => $extension
->getName(),
]);
}
}
}
public function rewriteConfig($original_config, $rewrite, $config_name, $extensionName) {
if (empty($original_config)) {
$message = 'Tried to rewrite config @config via @module module without initial config present.';
$this->logger
->error($message, [
'@config' => $config_name,
'@module' => $extensionName,
]);
throw new NonexistentInitialConfigException("Tried to rewrite config {$config_name} by {$extensionName} module without initial config.");
}
if (isset($rewrite['config_rewrite']) && $rewrite['config_rewrite'] == 'replace') {
$rewritten_config = $rewrite;
}
else {
$rewritten_config = NestedArray::mergeDeep($original_config, $rewrite);
}
if (isset($rewrite['config_rewrite']['replace']) && is_array($rewrite['config_rewrite']['replace'])) {
foreach ($rewrite['config_rewrite']['replace'] as $key) {
$parts = explode('.', $key);
$key_exists = NULL;
$value = NestedArray::getValue($rewrite, $parts, $key_exists);
if ($key_exists) {
NestedArray::setValue($rewritten_config, $parts, $value, TRUE);
}
else {
NestedArray::unsetValue($rewritten_config, $parts);
}
}
}
return $rewritten_config;
}
protected function fileScanDirectory($dir, $mask, $options = array()) {
return $this->fileSystem
->scanDirectory($dir, $mask, $options);
}
}