Test Failed
Pull Request — master (#872)
by Maxim
10:54 queued 03:52
created

PromptArguments::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 0
dl 0
loc 3
rs 10
c 1
b 0
f 0
cc 1
nc 1
nop 1
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
/**
17
 * @internal
18
 */
19
final class PromptArguments
20
{
21
    public function __construct(
22
        private readonly ReaderInterface $reader = new AttributeReader()
23
    ) {
24
    }
25
26
    public function promptMissedArguments(Command $command, InputInterface $input, OutputInterface $output): void
27
    {
28
        $io = new SymfonyStyle($input, $output);
29
30
        foreach ($command->getDefinition()->getArguments() as $argument) {
31
            // Skip default argument "the command to execute"
32
            if ($argument->getName() === 'command') {
33
                continue;
34
            }
35
36
            if ($argument->isRequired() && $input->getArgument($argument->getName()) === null) {
37
                $input->setArgument(
38
                    $argument->getName(),
39
                    $io->ask($this->getQuestion($command, $argument))
40
                );
41
            }
42
        }
43
    }
44
45
    private function getQuestion(Command $command, InputArgument $argument): string
46
    {
47
        $reflection = new \ReflectionClass($command);
48
49
        foreach ($this->reader->getClassMetadata($reflection, Question::class) as $question) {
50
            if ($question->argument === null) {
51
                throw new ConsoleException(
52
                    'When using a `Question` attribute on a console command class, the argument parameter is required.'
53
                );
54
            }
55
56
            if ($argument->getName() === $question->argument) {
57
                return $question->question;
58
            }
59
        }
60
61
        foreach ($reflection->getProperties() as $property) {
62
            $question = $this->reader->firstPropertyMetadata($property, Question::class);
63
            if ($question === null) {
64
                continue;
65
            }
66
67
            if ($argument->getName() === ($question->argument ?? $property->getName())) {
68
                return $question->question;
69
            }
70
        }
71
72
        return \sprintf('Please provide a value for the `%s` argument', $argument->getName());
73
    }
74
}
75