Completed
Push — master ( 66ec7e...c9ec0a )
by Matze
07:32
created

ConsoleCompilerPass::formatDefinition()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 21
ccs 12
cts 12
cp 1
rs 9.3142
cc 3
eloc 12
nc 2
nop 1
crap 3
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 2
    public function process(ContainerBuilder $container)
28
    {
29 2
        $console = $container->getDefinition('Console');
30 2
        $console->addMethodCall('setAutoExit', [false]);
31
32 2
        $taggedServices = $container->findTaggedServiceIds(self::TAG);
33
34 2
        $commands = [];
35 2
        foreach (array_keys($taggedServices) as $serviceId) {
36
            /** @var Command $command */
37 2
            $command = $container->get($serviceId);
38
39 2
            $proxyService = new Definition(ProxyCommand::class, [
40 2
                new Reference('service_container'),
41 2
                new Reference('Console'),
42 2
                $serviceId,
43 2
                $command->getName(),
44 2
                $command->getDescription(),
45 2
                $command->getAliases(),
46 2
                $this->formatDefinition($command->getDefinition())
47
            ]);
48 2
            $commands[] = $proxyService;
49
        }
50
51 2
        $console->addMethodCall('addCommands', [$commands]);
52 2
    }
53
54
    /**
55
     * @param InputDefinition $definition
56
     * @return array
57
     */
58 2
    private function formatDefinition(InputDefinition $definition)
59
    {
60 2
        $arguments = $this->getArguments($definition);
61
62 2
        foreach ($definition->getOptions() as $option) {
63 2
            $mode = $this->getOptionMode($option);
64
65 2
            $arguments[] = new Definition(
66 2
                InputOption::class,
67
                [
68 2
                    $option->getName(),
69 2
                    $option->getShortcut(),
70 2
                    $mode,
71 2
                    $option->getDescription(),
72 2
                    $option->getDefault() ?: null
73
                ]
74
            );
75
        }
76
77 2
        return $arguments;
78
    }
79
80
    /**
81
     * @param InputArgument $argument
82
     * @return int
83
     */
84 2
    private function getArgumentMode(InputArgument $argument)
85
    {
86 2
        $mode = 0;
87 2
        if ($argument->isRequired()) {
88 2
            $mode |= InputArgument::REQUIRED;
89
        }
90 2
        if ($argument->isArray()) {
91
            $mode |= InputArgument::IS_ARRAY;
92
        }
93 2
        if (!$argument->isRequired()) {
94 2
            $mode |= InputArgument::OPTIONAL;
95
        }
96
97 2
        return $mode;
98
    }
99
100
    /**
101
     * @param InputOption $option
102
     * @return int
103
     */
104 2
    private function getOptionMode(InputOption $option)
105
    {
106 2
        $mode = 0;
107 2
        if ($option->isArray()) {
108
            $mode |= InputOption::VALUE_IS_ARRAY;
109
        }
110 2
        if ($option->isValueOptional()) {
111
            $mode |= InputOption::VALUE_OPTIONAL;
112
        }
113 2
        if ($option->isValueRequired()) {
114
            $mode |= InputOption::VALUE_REQUIRED;
115
        }
116 2
        if (!$mode) {
117 2
            $mode = InputOption::VALUE_NONE;
118
        }
119
120 2
        return $mode;
121
    }
122
123
    /**
124
     * @param InputDefinition $definition
125
     * @return array
126
     */
127 2
    private function getArguments(InputDefinition $definition) : array
128
    {
129 2
        $arguments = [];
130
131 2
        foreach ($definition->getArguments() as $argument) {
132 2
            $mode = $this->getArgumentMode($argument);
133
134 2
            $arguments[] = new Definition(InputArgument::class, [
135 2
                $argument->getName(),
136 2
                $mode,
137 2
                $argument->getDescription(),
138 2
                $argument->getDefault()
139
            ]);
140
        }
141
142 2
        return $arguments;
143
    }
144
}
145