2 namespace Consolidation\Config\Inject;
4 use Consolidation\Config\ConfigInterface;
5 use Consolidation\Config\Util\ConfigFallback;
7 use Symfony\Component\Console\ConsoleEvents;
8 use Symfony\Component\Console\Event\ConsoleCommandEvent;
9 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
10 use Symfony\Component\Console\Application;
11 use Symfony\Component\Console\Input\InputOption;
13 class ConfigForCommand implements EventSubscriberInterface
16 protected $application;
18 public function __construct(ConfigInterface $config)
20 $this->config = $config;
23 public function setApplication(Application $application)
25 $this->application = $application;
31 public static function getSubscribedEvents()
33 return [ConsoleEvents::COMMAND => 'injectConfiguration'];
37 * Before a Console command runs, inject configuration settings
38 * for this command into the default value of the options of
41 * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event
43 public function injectConfiguration(ConsoleCommandEvent $event)
45 $command = $event->getCommand();
46 $this->injectConfigurationForGlobalOptions($event->getInput());
47 $this->injectConfigurationForCommand($command, $event->getInput());
49 $targetOfHelpCommand = $this->getHelpCommandTarget($command, $event->getInput());
50 if ($targetOfHelpCommand) {
51 $this->injectConfigurationForCommand($targetOfHelpCommand, $event->getInput());
55 protected function injectConfigurationForGlobalOptions($input)
57 if (!$this->application) {
61 $configGroup = new ConfigFallback($this->config, 'options');
63 $definition = $this->application->getDefinition();
64 $options = $definition->getOptions();
66 return $this->injectConfigGroupIntoOptions($configGroup, $options, $input);
69 protected function injectConfigurationForCommand($command, $input)
71 $commandName = $command->getName();
72 $commandName = str_replace(':', '.', $commandName);
73 $configGroup = new ConfigFallback($this->config, $commandName, 'command.', '.options.');
75 $definition = $command->getDefinition();
76 $options = $definition->getOptions();
78 return $this->injectConfigGroupIntoOptions($configGroup, $options, $input);
81 protected function injectConfigGroupIntoOptions($configGroup, $options, $input)
83 foreach ($options as $option => $inputOption) {
84 $key = str_replace('.', '-', $option);
85 $value = $configGroup->get($key);
86 if ($value !== null) {
87 if (is_bool($value) && ($value == true)) {
88 $input->setOption($key, $value);
89 } elseif ($inputOption->acceptValue()) {
90 $inputOption->setDefault($value);
96 protected function getHelpCommandTarget($command, $input)
98 if (($command->getName() != 'help') || (!isset($this->application))) {
102 $this->fixInputForSymfony2($command, $input);
104 // Symfony Console helpfully swaps 'command_name' and 'command'
105 // depending on whether the user entered `help foo` or `--help foo`.
106 // One of these is always `help`, and the other is the command we
107 // are actually interested in.
108 $nameOfCommandToDescribe = $input->getArgument('command_name');
109 if ($nameOfCommandToDescribe == 'help') {
110 $nameOfCommandToDescribe = $input->getArgument('command');
112 return $this->application->find($nameOfCommandToDescribe);
115 protected function fixInputForSymfony2($command, $input)
117 // Symfony 3.x prepares $input for us; Symfony 2.x, on the other
118 // hand, passes it in prior to binding with the command definition,
119 // so we have to go to a little extra work. It may be inadvisable
120 // to do these steps for commands other than 'help'.
121 if (!$input->hasArgument('command_name')) {
122 $command->ignoreValidationErrors();
123 $command->mergeApplicationDefinition();
124 $input->bind($command->getDefinition());