5 * Contains \Drupal\Console\Command\Config\ImportSingleCommand.
7 namespace Drupal\Console\Command\Config;
9 use Drupal\config\StorageReplaceDataWrapper;
10 use Drupal\Console\Core\Command\Shared\CommandTrait;
11 use Drupal\Console\Core\Style\DrupalStyle;
12 use Drupal\Core\Config\CachedStorage;
13 use Drupal\Core\Config\ConfigImporter;
14 use Drupal\Core\Config\ConfigImporterException;
15 use Drupal\Core\Config\ConfigManager;
16 use Drupal\Core\Config\StorageComparer;
17 use Symfony\Component\Console\Command\Command;
18 use Symfony\Component\Console\Input\InputArgument;
19 use Symfony\Component\Console\Input\InputInterface;
20 use Symfony\Component\Console\Input\InputOption;
21 use Symfony\Component\Console\Output\OutputInterface;
22 use Symfony\Component\Yaml\Parser;
24 class ImportSingleCommand extends Command
31 protected $configStorage;
36 protected $configManager;
39 * ImportSingleCommand constructor.
41 * @param CachedStorage $configStorage
42 * @param ConfigManager $configManager
44 public function __construct(
45 CachedStorage $configStorage,
46 ConfigManager $configManager
48 $this->configStorage = $configStorage;
49 $this->configManager = $configManager;
50 parent::__construct();
56 protected function configure()
59 ->setName('config:import:single')
60 ->setDescription($this->trans('commands.config.import.single.description'))
64 InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
65 $this->trans('commands.config.import.single.options.name')
69 InputOption::VALUE_OPTIONAL,
70 $this->trans('commands.config.import.single.options.file')
74 InputOption::VALUE_OPTIONAL,
75 $this->trans('commands.config.import.arguments.directory')
82 protected function execute(InputInterface $input, OutputInterface $output)
84 $io = new DrupalStyle($input, $output);
86 $name = $input->getOption('name');
87 $name = is_array($name) ? $name : [$name];
88 $directory = $input->getOption('directory');
89 $file = $input->getOption('file');
91 if (!$file && !$directory) {
92 $directory = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
95 $ymlFile = new Parser();
97 $source_storage = new StorageReplaceDataWrapper(
101 foreach ($name as $nameItem) {
102 // Allow for accidental .yml extension.
103 if (substr($nameItem, -4) === '.yml') {
104 $nameItem = substr($nameItem, 0, -4);
107 $configFile = count($name) == 1 ?
109 $directory.DIRECTORY_SEPARATOR.$nameItem.'.yml';
111 if (file_exists($configFile)) {
112 $value = $ymlFile->parse(file_get_contents($configFile));
113 $source_storage->delete($nameItem);
114 $source_storage->write($nameItem, $value);
118 $io->error($this->trans('commands.config.import.single.messages.empty-value'));
122 $storageComparer = new StorageComparer(
124 $this->configStorage,
129 if ($this->configImport($io, $storageComparer)) {
133 'commands.config.import.single.messages.success'
139 } catch (\Exception $e) {
140 $io->error($e->getMessage());
146 private function configImport($io, StorageComparer $storageComparer)
148 $configImporter = new ConfigImporter(
150 \Drupal::service('event_dispatcher'),
151 \Drupal::service('config.manager'),
153 \Drupal::service('config.typed'),
154 \Drupal::moduleHandler(),
155 \Drupal::service('module_installer'),
156 \Drupal::service('theme_handler'),
157 \Drupal::service('string_translation')
160 if ($configImporter->alreadyImporting()) {
161 $io->success($this->trans('commands.config.import.messages.already-imported'));
164 if ($configImporter->validate()) {
165 $sync_steps = $configImporter->initialize();
167 foreach ($sync_steps as $step) {
170 $configImporter->doSyncStep($step, $context);
171 } while ($context['finished'] < 1);
176 } catch (ConfigImporterException $e) {
177 $message = 'The import failed due to the following reasons:' . "\n";
178 $message .= implode("\n", $configImporter->getErrors());
181 $this->trans('commands.site.import.local.messages.error-writing'),
185 } catch (\Exception $e) {
188 $this->trans('commands.site.import.local.messages.error-writing'),
199 protected function interact(InputInterface $input, OutputInterface $output)
201 $io = new DrupalStyle($input, $output);
202 $name = $input->getOption('name');
203 $file = $input->getOption('file');
204 $directory = $input->getOption('directory');
208 $this->trans('commands.config.import.single.questions.name')
210 $input->setOption('name', $name);
213 if (!$directory && !$file) {
214 $file = $io->askEmpty(
215 $this->trans('commands.config.import.single.questions.file')
217 $input->setOption('file', $file);
221 if (!$file && !$directory) {
222 $directory = $io->askEmpty(
223 $this->trans('commands.config.import.single.questions.directory')
225 $input->setOption('directory', $directory);