Passed
Push — master ( 8bea99...a169e2 )
by Paweł
02:07
created

CommandsLoader   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 37
c 4
b 0
f 0
dl 0
loc 77
rs 10
wmc 11

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A getCommandNameFromServer() 0 3 1
B runCommandFromName() 0 43 8
A registerCommand() 0 3 1
1
<?php
2
3
namespace pjpawel\LightApi\Command;
4
5
use Exception;
6
use pjpawel\LightApi\Command\Input\Stdin;
7
use pjpawel\LightApi\Command\Internal\DebugCommand;
8
use pjpawel\LightApi\Command\Internal\KernelAwareCommand;
9
use pjpawel\LightApi\Command\Output\Stdout;
10
use pjpawel\LightApi\Container\ClassDefinition;
11
use pjpawel\LightApi\Container\ContainerLoader;
12
use pjpawel\LightApi\Container\LazyServiceInterface;
13
use pjpawel\LightApi\Kernel;
14
use ReflectionClass;
15
use ReflectionNamedType;
16
17
class CommandsLoader
18
{
19
20
    private const KERNEL_COMMANDS = [
21
        'kernel:debug' => DebugCommand::class
22
    ];
23
24
    /**
25
     * @var array<string,string>
26
     */
27
    public array $command = [];
28
29
    
30
    public function __construct()
31
    {
32
        $this->command = self::KERNEL_COMMANDS;
33
    }
34
35
    public function registerCommand(string $commandName, string $className): void
36
    {
37
        $this->command[$commandName] = $className;
38
    }
39
40
    /**
41
     * @param string $commandName
42
     * @param ContainerLoader $container
43
     * @return int
44
     */
45
    public function runCommandFromName(string $commandName, ContainerLoader $container, ?Kernel $kernel = null): int
46
    {
47
        $stdout = new Stdout();
48
        try {
49
            $className = $this->command[$commandName];
50
            $reflectionClass = new ReflectionClass($className);
51
            $constructor = $reflectionClass->getConstructor();
52
            if ($constructor !== null) {
53
                /** @var ClassDefinition $classDefinition */
54
                $classDefinition = $container->get($className);
55
                $args = $classDefinition->arguments;
56
                foreach ($constructor->getParameters() as $parameter) {
57
                    $parameterType = $parameter->getType();
58
                    if ($parameterType instanceof ReflectionNamedType) {
59
                        $args[] = $container->get($parameterType->getName());
60
                    }
61
                }
62
            } else {
63
                $args = [];
64
            }
65
            $stdin = new Stdin();
66
            /** @var Command $command */
67
            $command = $reflectionClass->newInstanceArgs($args);
68
            $command->prepare($stdin);
69
            /* Prepare input */
70
            $stdin->load();
71
            /* Inject services */
72
            if (is_subclass_of($command, LazyServiceInterface::class)) {
73
                $command->setContainer($container->prepareContainerBag($command::getAllServices()));
0 ignored issues
show
Bug introduced by
The method setContainer() does not exist on pjpawel\LightApi\Command\Command. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
                $command->/** @scrutinizer ignore-call */ 
74
                          setContainer($container->prepareContainerBag($command::getAllServices()));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method getAllServices() does not exist on pjpawel\LightApi\Command\Command. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
                $command->setContainer($container->prepareContainerBag($command::/** @scrutinizer ignore-call */ getAllServices()));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
74
            }
75
            /* If $command is KernelAwareCommand set Kernel */
76
            if (!is_null($kernel) && is_subclass_of($command, KernelAwareCommand::class)) {
77
                $command->setKernel($kernel);
0 ignored issues
show
Bug introduced by
The method setKernel() does not exist on pjpawel\LightApi\Command\Command. It seems like you code against a sub-type of pjpawel\LightApi\Command\Command such as pjpawel\LightApi\Command...rnal\KernelAwareCommand. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

77
                $command->/** @scrutinizer ignore-call */ 
78
                          setKernel($kernel);
Loading history...
78
            }
79
            return $command->execute($stdin, $stdout);
80
        } catch (Exception $e) {
81
            $stdout->writeln([
82
                'Exception thrown during command',
83
                $e->getMessage(),
84
                'file: ' . $e->getFile(),
85
                'line: ' . $e->getLine()
86
            ]);
87
            return Command::FAILURE;
88
        }
89
    }
90
91
    public function getCommandNameFromServer(): string
92
    {
93
        return $_SERVER['argv'][0];
94
    }
95
}