Passed
Push — master ( 1157cf...cd5eb5 )
by Melech
01:25
created

Output::getWriters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 4
rs 10
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\Interaction\Output;
15
16
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Valkyrja\Cli\Interaction\Enum\ExitCode;
18
use Valkyrja\Cli\Interaction\Message\Contract\MessageContract;
19
use Valkyrja\Cli\Interaction\Output\Contract\OutputContract as Contract;
20
use Valkyrja\Cli\Interaction\Writer\Contract\WriterContract;
21
use Valkyrja\Cli\Interaction\Writer\QuestionWriter;
22
23
class Output implements Contract
24
{
25
    /**
26
     * The unwritten messages.
27
     *
28
     * @var MessageContract[]
29
     */
30
    protected array $unwrittenMessages = [];
31
32
    /**
33
     * The written messages.
34
     *
35
     * @var MessageContract[]
36
     */
37
    protected array $writtenMessages = [];
38
39
    /**
40
     * The message writers.
41
     *
42
     * @var WriterContract[]
43
     */
44
    protected array $writers = [];
45
46
    public function __construct(
47
        protected bool $isInteractive = true,
48
        protected bool $isQuiet = false,
49
        protected bool $isSilent = false,
50
        protected ExitCode|int $exitCode = ExitCode::SUCCESS,
51
        MessageContract ...$messages,
52
    ) {
53
        $this->unwrittenMessages = $messages;
54
55
        $this->writers = [
56
            new QuestionWriter(),
57
        ];
58
    }
59
60
    /**
61
     * @inheritDoc
62
     *
63
     * @return MessageContract[]
64
     */
65
    #[Override]
66
    public function getMessages(): array
67
    {
68
        return [
69
            ...$this->writtenMessages,
70
            ...$this->unwrittenMessages,
71
        ];
72
    }
73
74
    /**
75
     * @inheritDoc
76
     *
77
     * @return MessageContract[]
78
     */
79
    #[Override]
80
    public function getWrittenMessages(): array
81
    {
82
        return $this->writtenMessages;
83
    }
84
85
    /**
86
     * @inheritDoc
87
     */
88
    #[Override]
89
    public function hasWrittenMessage(): bool
90
    {
91
        return $this->writtenMessages !== [];
92
    }
93
94
    /**
95
     * @inheritDoc
96
     *
97
     * @return MessageContract[]
98
     */
99
    #[Override]
100
    public function getUnwrittenMessages(): array
101
    {
102
        return $this->unwrittenMessages;
103
    }
104
105
    /**
106
     * @inheritDoc
107
     */
108
    #[Override]
109
    public function hasUnwrittenMessage(): bool
110
    {
111
        return $this->unwrittenMessages !== [];
112
    }
113
114
    /**
115
     * @inheritDoc
116
     */
117
    #[Override]
118
    public function withMessages(MessageContract ...$messages): static
119
    {
120
        $new = clone $this;
121
122
        $new->unwrittenMessages = $messages;
123
124
        return $new;
125
    }
126
127
    /**
128
     * @inheritDoc
129
     */
130
    #[Override]
131
    public function withAddedMessages(MessageContract ...$messages): static
132
    {
133
        $new = clone $this;
134
135
        $new->unwrittenMessages = [
0 ignored issues
show
Documentation Bug introduced by
It seems like array($new->unwrittenMessages, $messages) of type array<integer,array|arra...tract\MessageContract>> is incompatible with the declared type Valkyrja\Cli\Interaction...tract\MessageContract[] of property $unwrittenMessages.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
136
            ...$new->unwrittenMessages,
137
            ...$messages,
138
        ];
139
140
        return $new;
141
    }
142
143
    /**
144
     * @inheritDoc
145
     */
146
    #[Override]
147
    public function withAddedMessage(MessageContract $message): static
148
    {
149
        $new = clone $this;
150
151
        $new->unwrittenMessages[] = $message;
152
153
        return $new;
154
    }
155
156
    /**
157
     * @inheritDoc
158
     */
159
    #[Override]
160
    public function writeMessages(): static
161
    {
162
        $new = clone $this;
163
164
        // Avoid writing messages twice or more if writeMessages is called in a callback within the foreach loop
165
        $unwrittenMessages = $this->unwrittenMessages;
166
        // Ensure all unwritten messages are truly removed
167
        $new->unwrittenMessages = [];
168
169
        foreach ($unwrittenMessages as $message) {
170
            $new = $new->writeMessageViaWriter($message);
171
        }
172
173
        return $new;
174
    }
175
176
    /**
177
     * @inheritDoc
178
     */
179
    #[Override]
180
    public function getWriters(): array
181
    {
182
        return $this->writers;
183
    }
184
185
    /**
186
     * @inheritDoc
187
     */
188
    #[Override]
189
    public function withWriters(WriterContract ...$writers): static
190
    {
191
        $new = clone $this;
192
193
        $new->writers = $writers;
194
195
        return $new;
196
    }
197
198
    /**
199
     * @inheritDoc
200
     */
201
    #[Override]
202
    public function isInteractive(): bool
203
    {
204
        return $this->isInteractive;
205
    }
206
207
    /**
208
     * @inheritDoc
209
     */
210
    #[Override]
211
    public function withIsInteractive(bool $isInteractive): static
212
    {
213
        $new = clone $this;
214
215
        $new->isInteractive = $isInteractive;
216
217
        return $new;
218
    }
219
220
    /**
221
     * @inheritDoc
222
     */
223
    #[Override]
224
    public function isQuiet(): bool
225
    {
226
        return $this->isQuiet;
227
    }
228
229
    /**
230
     * @inheritDoc
231
     */
232
    #[Override]
233
    public function withIsQuiet(bool $isQuiet): static
234
    {
235
        $new = clone $this;
236
237
        $new->isQuiet = $isQuiet;
238
239
        return $new;
240
    }
241
242
    /**
243
     * @inheritDoc
244
     */
245
    #[Override]
246
    public function isSilent(): bool
247
    {
248
        return $this->isSilent;
249
    }
250
251
    /**
252
     * @inheritDoc
253
     */
254
    #[Override]
255
    public function withIsSilent(bool $isSilent): static
256
    {
257
        $new = clone $this;
258
259
        $new->isSilent = $isSilent;
260
261
        return $new;
262
    }
263
264
    /**
265
     * @inheritDoc
266
     */
267
    #[Override]
268
    public function getExitCode(): ExitCode|int
269
    {
270
        return $this->exitCode;
271
    }
272
273
    /**
274
     * @inheritDoc
275
     */
276
    #[Override]
277
    public function withExitCode(ExitCode|int $exitCode): static
278
    {
279
        $new = clone $this;
280
281
        $new->exitCode = $exitCode;
282
283
        return $new;
284
    }
285
286
    /**
287
     * @inheritDoc
288
     */
289
    #[Override]
290
    public function writeMessage(MessageContract $message): static
291
    {
292
        $this->setMessageAsWritten($message);
293
294
        if ($this->isSilent || ($this->isQuiet && $this->exitCode === ExitCode::SUCCESS)) {
295
            return $this;
296
        }
297
298
        $this->outputMessage($message);
299
300
        return $this;
301
    }
302
303
    /**
304
     * Write a message through a writer.
305
     *
306
     * @param MessageContract $message The message
307
     *
308
     * @return static
309
     */
310
    protected function writeMessageViaWriter(MessageContract $message): static
311
    {
312
        foreach ($this->writers as $writer) {
313
            if ($writer->shouldWriteMessage($message)) {
314
                return $writer->write($this, $message);
315
            }
316
        }
317
318
        return $this->writeMessage($message);
319
    }
320
321
    /**
322
     * Set a message as written.
323
     *
324
     * @param MessageContract $message The message
325
     *
326
     * @return void
327
     */
328
    protected function setMessageAsWritten(MessageContract $message): void
329
    {
330
        $this->writtenMessages[] = $message;
331
    }
332
333
    /**
334
     * Output a message.
335
     *
336
     * @param MessageContract $message The message
337
     *
338
     * @return void
339
     */
340
    protected function outputMessage(MessageContract $message): void
341
    {
342
        echo $message->getFormattedText();
343
    }
344
}
345