Completed
Push — master ( 59c475...436a5a )
by Greg
02:13
created

ConfigForCommand::injectConfigGroupIntoOptions()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 3
eloc 6
nc 3
nop 2
1
<?php
2
namespace Consolidation\Config\Inject;
3
4
use Consolidation\Config\ConfigInterface;
5
use Consolidation\Config\Util\ConfigFallback;
6
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
12
class ConfigForCommand implements EventSubscriberInterface
13
{
14
    protected $config;
15
    protected $application;
16
17
    public function __construct(ConfigInterface $config)
18
    {
19
        $this->config = $config;
20
    }
21
22
    public function setApplication(Application $application)
23
    {
24
        $this->application = $application;
25
    }
26
27
    /**
28
     * {@inheritdoc}
29
     */
30
    public static function getSubscribedEvents()
31
    {
32
        return [ConsoleEvents::COMMAND => 'injectConfiguration'];
33
    }
34
35
    /**
36
     * Before a Console command runs, inject configuration settings
37
     * for this command into the default value of the options of
38
     * this command.
39
     *
40
     * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event
41
     */
42
    public function injectConfiguration(ConsoleCommandEvent $event)
43
    {
44
        $command = $event->getCommand();
45
        $this->injectConfigurationForGlobalOptions();
46
        $this->injectConfigurationForCommand($command);
47
48
        $targetOfHelpCommand = $this->getHelpCommandTarget($command, $event->getInput());
49
        if ($targetOfHelpCommand) {
50
            $this->injectConfigurationForCommand($targetOfHelpCommand);
51
        }
52
    }
53
54
    protected function injectConfigurationForGlobalOptions()
55
    {
56
        if (!$this->application) {
57
            return;
58
        }
59
60
        $configGroup = new ConfigFallback($this->config, 'options');
61
62
        $definition = $this->application->getDefinition();
63
        $options = $definition->getOptions();
64
65
        return $this->injectConfigGroupIntoOptions($configGroup, $options);
66
    }
67
68
    protected function injectConfigurationForCommand($command)
69
    {
70
        $commandName = $command->getName();
71
        $commandName = str_replace(':', '.', $commandName);
72
        $configGroup = new ConfigFallback($this->config, $commandName, 'command.', '.options.');
73
74
        $definition = $command->getDefinition();
75
        $options = $definition->getOptions();
76
77
        return $this->injectConfigGroupIntoOptions($configGroup, $options);
78
    }
79
80
    protected function injectConfigGroupIntoOptions($configGroup, $options)
81
    {
82
        foreach ($options as $option => $inputOption) {
83
            $key = str_replace('.', '-', $option);
84
            $value = $configGroup->get($key);
85
            if ($value !== null) {
86
                $inputOption->setDefault($value);
87
            }
88
        }
89
    }
90
91
    protected function getHelpCommandTarget($command, $input)
92
    {
93
        if (($command->getName() != 'help') || (!isset($this->application))) {
94
            return false;
95
        }
96
97
        $this->fixInputForSymfony2($command, $input);
98
99
        // Symfony Console helpfully swaps 'command_name' and 'command'
100
        // depending on whether the user entered `help foo` or `--help foo`.
101
        // One of these is always `help`, and the other is the command we
102
        // are actually interested in.
103
        $nameOfCommandToDescribe = $input->getArgument('command_name');
104
        if ($nameOfCommandToDescribe == 'help') {
105
            $nameOfCommandToDescribe = $input->getArgument('command');
106
        }
107
        return $this->application->find($nameOfCommandToDescribe);
108
    }
109
110
    protected function fixInputForSymfony2($command, $input)
111
    {
112
        // Symfony 3.x prepares $input for us; Symfony 2.x, on the other
113
        // hand, passes it in prior to binding with the command definition,
114
        // so we have to go to a little extra work.  It may be inadvisable
115
        // to do these steps for commands other than 'help'.
116
        if (!$input->hasArgument('command_name')) {
117
            $command->ignoreValidationErrors();
118
            $command->mergeApplicationDefinition();
119
            $input->bind($command->getDefinition());
120
        }
121
    }
122
}
123