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 $directory = $input->getOption('directory');
88 $file = $input->getOption('file');
90 if (!$file && !$directory) {
91 $directory = config_get_config_directory(CONFIG_SYNC_DIRECTORY);
94 $ymlFile = new Parser();
96 $source_storage = new StorageReplaceDataWrapper(
100 foreach ($name as $nameItem) {
101 // Allow for accidental .yml extension.
102 if (substr($nameItem, -4) === '.yml') {
103 $nameItem = substr($nameItem, 0, -4);
106 $configFile = $directory.DIRECTORY_SEPARATOR.$nameItem.'.yml';
107 if (file_exists($configFile)) {
108 $value = $ymlFile->parse(file_get_contents($configFile));
109 $source_storage->replaceData($nameItem, $value);
113 $io->error($this->trans('commands.config.import.single.messages.empty-value'));
117 $storageComparer = new StorageComparer(
119 $this->configStorage,
123 if ($this->configImport($io, $storageComparer)) {
127 'commands.config.import.single.messages.success'
133 } catch (\Exception $e) {
134 $io->error($e->getMessage());
140 private function configImport($io, StorageComparer $storageComparer)
142 $configImporter = new ConfigImporter(
144 \Drupal::service('event_dispatcher'),
145 \Drupal::service('config.manager'),
147 \Drupal::service('config.typed'),
148 \Drupal::moduleHandler(),
149 \Drupal::service('module_installer'),
150 \Drupal::service('theme_handler'),
151 \Drupal::service('string_translation')
154 if ($configImporter->alreadyImporting()) {
155 $io->success($this->trans('commands.config.import.messages.already-imported'));
158 if ($configImporter->validate()) {
159 $sync_steps = $configImporter->initialize();
161 foreach ($sync_steps as $step) {
164 $configImporter->doSyncStep($step, $context);
165 } while ($context['finished'] < 1);
170 } catch (ConfigImporterException $e) {
171 $message = 'The import failed due for the following reasons:' . "\n";
172 $message .= implode("\n", $configImporter->getErrors());
175 $this->trans('commands.site.import.local.messages.error-writing'),
179 } catch (\Exception $e) {
182 $this->trans('commands.site.import.local.messages.error-writing'),
193 protected function interact(InputInterface $input, OutputInterface $output)
195 $io = new DrupalStyle($input, $output);
196 $name = $input->getOption('name');
197 $file = $input->getOption('file');
198 $directory = $input->getOption('directory');
202 $this->trans('commands.config.import.single.questions.name')
204 $input->setOption('name', $name);
207 if (!$directory && !$file) {
208 $file = $io->askEmpty(
209 $this->trans('commands.config.import.single.questions.file')
211 $input->setOption('file', $file);
215 if (!$file && !$directory) {
216 $directory = $io->askEmpty(
217 $this->trans('commands.config.import.single.questions.directory')
219 $input->setOption('directory', $directory);