Completed
Push — master ( ba9072...49bd4f )
by Matze
06:56
created

ConsoleCompilerPass::formatDefinition()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 4.0629

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 29
ccs 16
cts 19
cp 0.8421
rs 8.5806
cc 4
eloc 17
nc 4
nop 1
crap 4.0629
1
<?php
2
3
namespace BrainExe\Core\DependencyInjection\CompilerPass;
4
5
use BrainExe\Core\Annotations\CompilerPass;
6
use BrainExe\Core\Console\ProxyCommand;
7
use Symfony\Component\Console\Command\Command;
8
use Symfony\Component\Console\Input\InputArgument;
9
use Symfony\Component\Console\Input\InputDefinition;
10
use Symfony\Component\Console\Input\InputOption;
11
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
12
use Symfony\Component\DependencyInjection\ContainerBuilder;
13
use Symfony\Component\DependencyInjection\Definition;
14
use Symfony\Component\DependencyInjection\Reference;
15
16
/**
17
 * @CompilerPass
18
 */
19
class ConsoleCompilerPass implements CompilerPassInterface
20
{
21
22
    const TAG = 'console';
23
24
    /**
25
     * {@inheritdoc}
26
     */
27 3
    public function process(ContainerBuilder $container)
28
    {
29 3
        $console = $container->getDefinition('Console');
30 3
        $console->addMethodCall('setAutoExit', [false]);
31
32 3
        $taggedServices = $container->findTaggedServiceIds(self::TAG);
33 3
        $commands = [];
34 3
        foreach (array_keys($taggedServices) as $serviceId) {
35
            /** @var Command $command */
36 3
            $command = $container->get($serviceId);
37
38 3
            $proxyService = new Definition(ProxyCommand::class, [
39 3
                new Reference('service_container'),
40 3
                new Reference('Console'),
41 3
                $serviceId,
42 3
                $command->getName(),
43 3
                $command->getDescription(),
44 3
                $command->getAliases(),
45 3
                $this->formatDefinition($command->getDefinition())
46
            ]);
47 3
            $commands[] = $proxyService;
48
        }
49
50 3
        $console->addMethodCall('addCommands', [$commands]);
51 3
    }
52
53
    /**
54
     * @param InputDefinition $definition
55
     * @return array
56
     */
57 3
    private function formatDefinition(InputDefinition $definition)
58
    {
59 3
        $arguments = [];
60
61 3
        foreach ($definition->getArguments() as $argument) {
62 2
            $mode = $this->getArgumentMode($argument);
63 2
64 2
            $arguments[] = new Definition(
65
                InputArgument::class,
66 2
                [$argument->getName(), $mode, $argument->getDescription(), $argument->getDefault()]
67
            );
68
        }
69 2
        foreach ($definition->getOptions() as $option) {
70 2
            $mode = $this->getOptionMode($option);
71
72
            $arguments[] = new Definition(
73 2
                InputOption::class,
74 2
                [
75 2
                    $option->getName(),
76
                    $option->getShortcut(),
77
                    $mode,
78 3
                    $option->getDescription(),
79 2
                    $option->getDefault() ?: null
80 2
                ]
81
            );
82
        }
83 2
84
        return $arguments;
85
    }
86 2
87
    /**
88
     * @param InputArgument $argument
89 2
     * @return int
90 2
     */
91
    private function getArgumentMode(InputArgument $argument)
92
    {
93 2
        $mode = 0;
94 2
        if ($argument->isRequired()) {
95
            $mode |= InputArgument::REQUIRED;
96 2
        }
97 2
        if ($argument->isArray()) {
98 2
            $mode |= InputArgument::IS_ARRAY;
99 2
        }
100 2
        if (!$argument->isRequired()) {
101
            $mode |= InputArgument::OPTIONAL;
102
        }
103
104
        return $mode;
105 3
    }
106
107
    /**
108
     * @param InputOption $option
109
     * @return int
110
     */
111
    private function getOptionMode(InputOption $option)
112
    {
113
        $mode = 0;
114
        if ($option->isArray()) {
115
            $mode |= InputOption::VALUE_IS_ARRAY;
116
        }
117
        if ($option->isValueOptional()) {
118
            $mode |= InputOption::VALUE_OPTIONAL;
119
        }
120
        if ($option->isValueRequired()) {
121
            $mode |= InputOption::VALUE_REQUIRED;
122
        }
123
        if (!$mode) {
124
            $mode = InputOption::VALUE_NONE;
125
        }
126
127
        return $mode;
128
    }
129
}
130