Test Failed
Pull Request — master (#872)
by Maxim
12:26 queued 05:23
created

PromptArguments   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 54
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 13
eloc 23
dl 0
loc 54
rs 10
c 1
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A promptMissedArguments() 0 14 5
A __construct() 0 3 1
B getQuestion() 0 28 7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Console;
6
7
use Spiral\Attributes\AttributeReader;
8
use Spiral\Attributes\ReaderInterface;
9
use Spiral\Console\Attribute\Question;
10
use Spiral\Console\Exception\ConsoleException;
11
use Symfony\Component\Console\Input\InputArgument;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Output\OutputInterface;
14
use Symfony\Component\Console\Style\SymfonyStyle;
15
16
class PromptArguments
17
{
18
    public function __construct(
19
        protected readonly ReaderInterface $reader = new AttributeReader()
20
    ) {
21
    }
22
23
    public function promptMissedArguments(Command $command, InputInterface $input, OutputInterface $output): void
24
    {
25
        $io = new SymfonyStyle($input, $output);
26
27
        foreach ($command->getDefinition()->getArguments() as $argument) {
28
            // Skip default argument "the command to execute"
29
            if ($argument->getName() === 'command') {
30
                continue;
31
            }
32
33
            if ($argument->isRequired() && $input->getArgument($argument->getName()) === null) {
34
                $input->setArgument(
35
                    $argument->getName(),
36
                    $io->ask($this->getQuestion($command, $argument))
37
                );
38
            }
39
        }
40
    }
41
42
    private function getQuestion(Command $command, InputArgument $argument): string
43
    {
44
        $reflection = new \ReflectionClass($command);
45
46
        foreach ($this->reader->getClassMetadata($reflection, Question::class) as $question) {
47
            if ($question->argument === null) {
48
                throw new ConsoleException(
49
                    'When using a `Question` attribute on a console command class, the argument parameter is required.'
50
                );
51
            }
52
53
            if ($argument->getName() === $question->argument) {
54
                return $question->question;
55
            }
56
        }
57
58
        foreach ($reflection->getProperties() as $property) {
59
            $question = $this->reader->firstPropertyMetadata($property, Question::class);
60
            if ($question === null) {
61
                continue;
62
            }
63
64
            if ($argument->getName() === ($question->argument ?? $property->getName())) {
65
                return $question->question;
66
            }
67
        }
68
69
        return \sprintf('Please provide a value for the `%s` argument', $argument->getName());
70
    }
71
}
72