CommandLineInterface::askConfirmation()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 14
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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