Passed
Push — master ( a8852d...e55d14 )
by Melech
04:21 queued 30s
created

AttributeCollector::getCommands()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 16
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Cli\Routing\Collector;
15
16
use ReflectionException;
17
use Valkyrja\Attribute\Contract\Attributes;
18
use Valkyrja\Cli\Routing\Attribute\Command as Attribute;
19
use Valkyrja\Cli\Routing\Collector\Contract\Collector as Contract;
20
use Valkyrja\Cli\Routing\Data\Command as Model;
21
use Valkyrja\Cli\Routing\Data\Contract\Command;
22
use Valkyrja\Reflection\Contract\Reflection;
23
24
/**
25
 * Class AttributeCollector.
26
 *
27
 * @author Melech Mizrachi
28
 */
29
class AttributeCollector implements Contract
30
{
31
    public function __construct(
32
        protected Attributes $attributes,
33
        protected Reflection $reflection,
34
    ) {
35
    }
36
37
    /**
38
     * Get the commands.
39
     *
40
     * @param class-string ...$classes The classes
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
41
     *
42
     * @throws ReflectionException
43
     *
44
     * @return Command[]
45
     */
46
    public function getCommands(string ...$classes): array
47
    {
48
        $commands = [];
49
50
        // Iterate through all the classes
51
        foreach ($classes as $class) {
52
            /** @var Attribute[] $attributes */
53
            $attributes = $this->attributes->forClassAndMembers($class, Attribute::class);
54
55
            // Get all the attributes for each class and iterate through them
56
            foreach ($attributes as $attribute) {
57
                $commands[] = $this->getCommandFromAttribute($attribute);
58
            }
59
        }
60
61
        return $commands;
62
    }
63
64
    /**
65
     * Get a command from an attribute.
66
     *
67
     * @param Command $attribute The attribute
68
     *
69
     * @throws ReflectionException
70
     *
71
     * @return Command
72
     */
73
    protected function getCommandFromAttribute(Command $attribute): Command
74
    {
75
        $dispatch = $attribute->getDispatch();
76
77
        $methodReflection = $this->reflection->forClassMethod($dispatch->getClass(), $dispatch->getMethod());
78
        $dependencies     = $this->reflection->getDependencies($methodReflection);
79
80
        return (new Model(
81
            name: $attribute->getName(),
82
            description: $attribute->getDescription(),
83
            helpText: $attribute->getHelpText(),
84
            dispatch: $attribute->getDispatch()->withDependencies($dependencies)
85
        ))->withArguments(...$attribute->getArguments())
86
          ->withOptions(...$attribute->getOptions());
87
    }
88
}
89