AlterOptionsCommandEvent   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 5
dl 0
loc 61
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A alterCommandOptions() 0 30 4
A findAndAddHookOptions() 0 7 2
A getSubscribedEvents() 0 4 1
1
<?php
2
namespace Consolidation\AnnotatedCommand\Options;
3
4
use Consolidation\AnnotatedCommand\AnnotatedCommand;
5
use Symfony\Component\Console\Application;
6
use Symfony\Component\Console\Command\Command;
7
use Symfony\Component\Console\ConsoleEvents;
8
use Symfony\Component\Console\Event\ConsoleCommandEvent;
9
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
10
11
/**
12
 * AlterOptionsCommandEvent is a subscriber to the Command Event
13
 * that looks up any additional options (e.g. from an OPTION_HOOK)
14
 * that should be added to the command.  Options need to be added
15
 * in two circumstances:
16
 *
17
 * 1. When 'help' for the command is called, so that the additional
18
 *    command options may be listed in the command description.
19
 *
20
 * 2. When the command itself is called, so that option validation
21
 *    may be done.
22
 *
23
 * We defer the addition of options until these times so that we
24
 * do not invoke the option hooks for every command on every run
25
 * of the program, and so that we do not need to defer the addition
26
 * of all of the application hooks until after all of the application
27
 * commands have been added. (Hooks may appear in the same command files
28
 * as command implementations; applications may support command file
29
 * plug-ins, and hooks may add options to commands defined in other
30
 * commandfiles.)
31
 */
32
class AlterOptionsCommandEvent implements EventSubscriberInterface
33
{
34
    /** var Application */
35
    protected $application;
36
37
    public function __construct(Application $application)
38
    {
39
        $this->application = $application;
40
    }
41
42
    /**
43
     * @param ConsoleCommandEvent $event
44
     */
45
    public function alterCommandOptions(ConsoleCommandEvent $event)
46
    {
47
        /* @var Command $command */
48
        $command = $event->getCommand();
49
        $input = $event->getInput();
50
        if ($command->getName() == 'help') {
51
            // Symfony 3.x prepares $input for us; Symfony 2.x, on the other
52
            // hand, passes it in prior to binding with the command definition,
53
            // so we have to go to a little extra work.  It may be inadvisable
54
            // to do these steps for commands other than 'help'.
55
            if (!$input->hasArgument('command_name')) {
56
                $command->ignoreValidationErrors();
57
                $command->mergeApplicationDefinition();
58
                $input->bind($command->getDefinition());
59
            }
60
61
            // Symfony Console helpfully swaps 'command_name' and 'command'
62
            // depending on whether the user entered `help foo` or `--help foo`.
63
            // One of these is always `help`, and the other is the command we
64
            // are actually interested in.
65
            $nameOfCommandToDescribe = $event->getInput()->getArgument('command_name');
66
            if ($nameOfCommandToDescribe == 'help') {
67
                $nameOfCommandToDescribe = $event->getInput()->getArgument('command');
68
            }
69
            $commandToDescribe = $this->application->find($nameOfCommandToDescribe);
0 ignored issues
show
Bug introduced by
It seems like $nameOfCommandToDescribe can also be of type array<integer,string> or null; however, Symfony\Component\Console\Application::find() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
70
            $this->findAndAddHookOptions($commandToDescribe);
71
        } else {
72
            $this->findAndAddHookOptions($command);
73
        }
74
    }
75
76
    public function findAndAddHookOptions($command)
77
    {
78
        if (!$command instanceof AnnotatedCommand) {
79
            return;
80
        }
81
        $command->optionsHook();
82
    }
83
84
85
    /**
86
     * @{@inheritdoc}
87
     */
88
    public static function getSubscribedEvents()
89
    {
90
        return [ConsoleEvents::COMMAND => 'alterCommandOptions'];
91
    }
92
}
93