ConfigForCommand   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 4
dl 0
loc 115
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setApplication() 0 4 1
A getSubscribedEvents() 0 4 1
A injectConfiguration() 0 11 2
A injectConfigurationForGlobalOptions() 0 13 2
A injectConfigurationForCommand() 0 11 1
A injectConfigGroupIntoOptions() 0 14 6
A getHelpCommandTarget() 0 18 4
A fixInputForSymfony2() 0 12 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
use Symfony\Component\Console\Input\InputOption;
12
13
class ConfigForCommand implements EventSubscriberInterface
14
{
15
    protected $config;
16
    protected $application;
17
18
    public function __construct(ConfigInterface $config)
19
    {
20
        $this->config = $config;
21
    }
22
23
    public function setApplication(Application $application)
24
    {
25
        $this->application = $application;
26
    }
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public static function getSubscribedEvents()
32
    {
33
        return [ConsoleEvents::COMMAND => 'injectConfiguration'];
34
    }
35
36
    /**
37
     * Before a Console command runs, inject configuration settings
38
     * for this command into the default value of the options of
39
     * this command.
40
     *
41
     * @param \Symfony\Component\Console\Event\ConsoleCommandEvent $event
42
     */
43
    public function injectConfiguration(ConsoleCommandEvent $event)
44
    {
45
        $command = $event->getCommand();
46
        $this->injectConfigurationForGlobalOptions($event->getInput());
47
        $this->injectConfigurationForCommand($command, $event->getInput());
48
49
        $targetOfHelpCommand = $this->getHelpCommandTarget($command, $event->getInput());
50
        if ($targetOfHelpCommand) {
51
            $this->injectConfigurationForCommand($targetOfHelpCommand, $event->getInput());
52
        }
53
    }
54
55
    protected function injectConfigurationForGlobalOptions($input)
56
    {
57
        if (!$this->application) {
58
            return;
59
        }
60
61
        $configGroup = new ConfigFallback($this->config, 'options');
62
63
        $definition = $this->application->getDefinition();
64
        $options = $definition->getOptions();
65
66
        return $this->injectConfigGroupIntoOptions($configGroup, $options, $input);
67
    }
68
69
    protected function injectConfigurationForCommand($command, $input)
70
    {
71
        $commandName = $command->getName();
72
        $commandName = str_replace(':', '.', $commandName);
73
        $configGroup = new ConfigFallback($this->config, $commandName, 'command.', '.options.');
74
75
        $definition = $command->getDefinition();
76
        $options = $definition->getOptions();
77
78
        return $this->injectConfigGroupIntoOptions($configGroup, $options, $input);
79
    }
80
81
    protected function injectConfigGroupIntoOptions($configGroup, $options, $input)
82
    {
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)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
88
                    $input->setOption($key, $value);
89
                } elseif ($inputOption->acceptValue()) {
90
                    $inputOption->setDefault($value);
91
                }
92
            }
93
        }
94
    }
95
96
    protected function getHelpCommandTarget($command, $input)
97
    {
98
        if (($command->getName() != 'help') || (!isset($this->application))) {
99
            return false;
100
        }
101
102
        $this->fixInputForSymfony2($command, $input);
103
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');
111
        }
112
        return $this->application->find($nameOfCommandToDescribe);
113
    }
114
115
    protected function fixInputForSymfony2($command, $input)
116
    {
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());
125
        }
126
    }
127
}
128