Passed
Push — master ( afb49b...f08be5 )
by Dorian
01:45
created

CommandLineInterface::write()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 2
1
<?php declare(strict_types=1);
2
3
namespace App\UI;
4
5
use Symfony\Component\Console\Command\Command;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Console\Output\OutputInterface;
8
use Symfony\Component\Console\Question\ConfirmationQuestion;
9
use Symfony\Component\Console\Question\Question;
10
11
final class CommandLineInterface implements UserInterface
12
{
13
    /** @var bool */
14
    private $dryRun;
15
16
    /** @var \Symfony\Component\Console\Command\Command */
17
    private $command;
18
19
    /** @var \Symfony\Component\Console\Input\InputInterface */
20
    private $input;
21
22
    /** @var \Symfony\Component\Console\Output\OutputInterface */
23
    private $output;
24
25
    /**
26
     * @param bool $dryRun
27
     * @param \Symfony\Component\Console\Command\Command $command
28
     * @param \Symfony\Component\Console\Input\InputInterface $input
29
     * @param \Symfony\Component\Console\Output\OutputInterface $output
30
     */
31
    public function __construct(bool $dryRun, Command $command, InputInterface $input, OutputInterface $output)
32
    {
33
        $this->dryRun = $dryRun;
34
        $this->command = $command;
35
        $this->input = $input;
36
        $this->output = $output;
37
38
        if ($dryRun) {
39
            $input->setInteractive(false);
40
        }
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function isInteractive(): bool
47
    {
48
        return $this->input->isInteractive();
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function isDryRun(): bool
55
    {
56
        return $this->dryRun;
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function askQuestion(string $message, $default = null): string
63
    {
64
        /** @var \Symfony\Component\Console\Helper\QuestionHelper $questionHelper */
65
        /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
66
        $questionHelper = $this->command->getHelper('question');
67
68
        /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
69
        $answer = $questionHelper->ask($this->input, $this->output, new Question($message, $default));
70
71
        if ($answer && $this->input->isInteractive()) {
72
            $this->writeln('');
73
        }
74
75
        return (string) $answer;
76
    }
77
78
    /**
79
     * {@inheritdoc}
80
     */
81
    private function askConfirmation(string $message, bool $default = true): bool
82
    {
83
        /** @var \Symfony\Component\Console\Helper\QuestionHelper $questionHelper */
84
        /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
85
        $questionHelper = $this->command->getHelper('question');
86
87
        /** @noinspection ExceptionsAnnotatingAndHandlingInspection */
88
        $answer = $questionHelper->ask($this->input, $this->output, new ConfirmationQuestion($message, $default));
89
90
        if ($answer && $this->input->isInteractive()) {
91
            $this->writeln('');
92
        }
93
94
        return $answer;
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100
    public function write($messages, bool $newLine = false): void
101
    {
102
        $this->output->write($messages, $newLine);
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    public function writeln($messages, int $options = 0): void
109
    {
110
        $this->output->writeln($messages, $options);
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116
    public function listing(array $messages, int $indentation = 0): void
117
    {
118
        $messages = array_map(function ($message) use ($indentation) {
119
            return sprintf(str_repeat(' ', $indentation).' * %s', $message);
120
        }, $messages);
121
122
        $this->write(PHP_EOL);
123
        $this->writeln($messages);
124
        $this->write(PHP_EOL);
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130
    public function forceOutput(callable $callable): void
131
    {
132
        $verbosity = $this->output->getVerbosity();
133
        $this->output->setVerbosity(OutputInterface::VERBOSITY_NORMAL);
134
135
        $callable();
136
137
        $this->output->setVerbosity($verbosity);
138
    }
139
140
    /**
141
     * {@inheritdoc}
142
     */
143
    public function indent(int $indentation = 1, int $characters = 2, string $character = ' '): string
144
    {
145
        return str_repeat(str_repeat($character, $characters), $indentation);
146
    }
147
148
    /**
149
     * {@inheritdoc}
150
     */
151
    public function confirm(bool $confirmationDefault = true): bool
152
    {
153
        $confirmationQuestion = '<question>Continue?</question> ('.($confirmationDefault ? 'Y/n' : 'y/N').') ';
154
        if (!$this->askConfirmation($confirmationQuestion, $confirmationDefault)) {
155
            $this->writeln(PHP_EOL.$this->indent().'Not doing anything...');
156
157
            return false;
158
        }
159
160
        return true;
161
    }
162
163
    /**
164
     * {@inheritdoc}
165
     */
166
    public function logError(string $error, array &$errors): void
167
    {
168
        $this->writeln('<error>An error occurred.</error>');
169
        $errors[] = $error;
170
    }
171
172
    /**
173
     * {@inheritdoc}
174
     */
175
    public function displayErrors(
176
        array $errors,
177
        string $process,
178
        string $type = 'error',
179
        int $indentation = 0
180
    ): void {
181
        $nbErrors = \count($errors);
182
        if ($nbErrors > 0) {
183
            $this->forceOutput(function () use ($nbErrors, $errors, $process, $type, $indentation) {
184
                $this->writeln(
185
                    PHP_EOL.PHP_EOL.'<'.$type.'>There were '.$nbErrors.' errors during the '.$process.' :</'.$type.'>'
186
                );
187
188
                $this->listing($errors, $indentation);
189
            });
190
        }
191
    }
192
}
193