Passed
Push — master ( 3cf8a9...a02fc4 )
by Gerrit
02:20
created

ServiceInvokeCommand::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 3
dl 0
loc 29
ccs 0
cts 15
cp 0
crap 2
rs 9.456
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright (C) 2019 Gerrit Addiks.
4
 * This package (including this file) was released under the terms of the GPL-3.0.
5
 * You should have received a copy of the GNU General Public License along with this program.
6
 * If not, see <http://www.gnu.org/licenses/> or send me a mail so i can send you a copy.
7
 *
8
 * @license GPL-3.0
9
 *
10
 * @author Gerrit Addiks <[email protected]>
11
 */
12
13
namespace Addiks\SymfonyGenerics\Commands;
14
15
use Addiks\SymfonyGenerics\Services\ArgumentCompilerInterface;
16
use Psr\Container\ContainerInterface;
17
use Webmozart\Assert\Assert;
18
use Symfony\Component\Console\Command\Command;
19
use ReflectionMethod;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Output\OutputInterface;
22
23
final class ServiceInvokeCommand extends Command
24
{
25
26
    /** @var ContainerInterface */
27
    private $container;
28
29
    /** @var ArgumentCompilerInterface */
30
    private $argumentCompiler;
31
32
    /** @var string */
33
    private $serviceId;
34
35
    /** @var object|null */
36
    private $service;
37
38
    /** @var string */
39
    private $method;
40
41
    /** @var array */
42
    private $arguments;
43
44
    /** @var string */
45
    private $name;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
46
47
    /** @var string */
48
    private $description;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
49
50
    public function __construct(
51
        ContainerInterface $container,
52
        ArgumentCompilerInterface $argumentCompiler,
53
        array $options
54
    ) {
55
        Assert::keyExists($options, 'service');
56
        Assert::keyExists($options, 'name');
57
58
        /** @var array<string, mixed> $defaults */
59
        $defaults = array(
60
            'arguments' => [],
61
            'method' => '__invoke',
62
            'description' => '',
63
        );
64
65
        $options = array_merge($defaults, $options);
66
67
        Assert::isArray($options['arguments']);
68
69
        $this->container = $container;
70
        $this->argumentCompiler = $argumentCompiler;
71
        $this->serviceId = $options['service'];
72
        $this->method = $options['method'];
73
        $this->arguments = $options['arguments'];
74
        $this->name = $options['name'];
75
        $this->description = $options['description'];
76
77
        parent::__construct();
78
    }
79
80
    protected function configure(): void
81
    {
82
        $this->setName($this->name);
83
84
        if (!empty($this->description)) {
85
            $this->setDescription($this->description);
86
        }
87
    }
88
89
    protected function execute(InputInterface $input, OutputInterface $output): int
90
    {
91
        /** @var object $service */
92
        $service = $this->service();
93
94
        $methodReflection = new ReflectionMethod($service, $this->method);
95
96
        /** @var array $arguments */
97
        $arguments = $this->argumentCompiler->buildCallArguments(
98
            $methodReflection,
99
            $this->arguments
100
        );
101
102
        $methodReflection->invoke($service, $arguments);
103
104
        return 0;
105
    }
106
107
    private function service(): object
108
    {
109
        if (is_null($this->service)) {
110
            $this->service = $this->container->get($this->serviceId);
111
        }
112
113
        return $this->service;
114
    }
115
116
}
117