Writer   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Importance

Changes 9
Bugs 0 Features 3
Metric Value
eloc 33
dl 0
loc 152
rs 10
c 9
b 0
f 3
wmc 18

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __call() 0 9 2
A write() 0 12 3
A table() 0 5 1
A __get() 0 7 3
A __construct() 0 11 4
A raw() 0 3 1
A colorizer() 0 3 1
A eol() 0 3 1
A doWrite() 0 7 2
1
<?php
2
3
/*
4
 * This file is part of the PHP-CLI package.
5
 *
6
 * (c) Jitendra Adhikari <[email protected]>
7
 *     <https://github.com/adhocore>
8
 *
9
 * Licensed under MIT license.
10
 */
11
12
namespace Ahc\Cli\Output;
13
14
/**
15
 * Cli Writer.
16
 *
17
 * @author  Jitendra Adhikari <[email protected]>
18
 * @license MIT
19
 *
20
 * @link    https://github.com/adhocore/cli
21
 *
22
 * @method Writer bgBlack($text, $eol = false)
23
 * @method Writer bgBlue($text, $eol = false)
24
 * @method Writer bgCyan($text, $eol = false)
25
 * @method Writer bgGreen($text, $eol = false)
26
 * @method Writer bgPurple($text, $eol = false)
27
 * @method Writer bgRed($text, $eol = false)
28
 * @method Writer bgWhite($text, $eol = false)
29
 * @method Writer bgYellow($text, $eol = false)
30
 * @method Writer black($text, $eol = false)
31
 * @method Writer blackBgBlue($text, $eol = false)
32
 * @method Writer blackBgCyan($text, $eol = false)
33
 * @method Writer blackBgGreen($text, $eol = false)
34
 * @method Writer blackBgPurple($text, $eol = false)
35
 * @method Writer blackBgRed($text, $eol = false)
36
 * @method Writer blackBgWhite($text, $eol = false)
37
 * @method Writer blackBgYellow($text, $eol = false)
38
 * @method Writer blue($text, $eol = false)
39
 * @method Writer blueBgBlack($text, $eol = false)
40
 * @method Writer blueBgCyan($text, $eol = false)
41
 * @method Writer blueBgGreen($text, $eol = false)
42
 * @method Writer blueBgPurple($text, $eol = false)
43
 * @method Writer blueBgRed($text, $eol = false)
44
 * @method Writer blueBgWhite($text, $eol = false)
45
 * @method Writer blueBgYellow($text, $eol = false)
46
 * @method Writer bold($text, $eol = false)
47
 * @method Writer boldBlack($text, $eol = false)
48
 * @method Writer boldBlackBgBlue($text, $eol = false)
49
 * @method Writer boldBlackBgCyan($text, $eol = false)
50
 * @method Writer boldBlackBgGreen($text, $eol = false)
51
 * @method Writer boldBlackBgPurple($text, $eol = false)
52
 * @method Writer boldBlackBgRed($text, $eol = false)
53
 * @method Writer boldBlackBgWhite($text, $eol = false)
54
 * @method Writer boldBlackBgYellow($text, $eol = false)
55
 * @method Writer boldBlue($text, $eol = false)
56
 * @method Writer boldBlueBgBlack($text, $eol = false)
57
 * @method Writer boldBlueBgCyan($text, $eol = false)
58
 * @method Writer boldBlueBgGreen($text, $eol = false)
59
 * @method Writer boldBlueBgPurple($text, $eol = false)
60
 * @method Writer boldBlueBgRed($text, $eol = false)
61
 * @method Writer boldBlueBgWhite($text, $eol = false)
62
 * @method Writer boldBlueBgYellow($text, $eol = false)
63
 * @method Writer boldCyan($text, $eol = false)
64
 * @method Writer boldCyanBgBlack($text, $eol = false)
65
 * @method Writer boldCyanBgBlue($text, $eol = false)
66
 * @method Writer boldCyanBgGreen($text, $eol = false)
67
 * @method Writer boldCyanBgPurple($text, $eol = false)
68
 * @method Writer boldCyanBgRed($text, $eol = false)
69
 * @method Writer boldCyanBgWhite($text, $eol = false)
70
 * @method Writer boldCyanBgYellow($text, $eol = false)
71
 * @method Writer boldGreen($text, $eol = false)
72
 * @method Writer boldGreenBgBlack($text, $eol = false)
73
 * @method Writer boldGreenBgBlue($text, $eol = false)
74
 * @method Writer boldGreenBgCyan($text, $eol = false)
75
 * @method Writer boldGreenBgPurple($text, $eol = false)
76
 * @method Writer boldGreenBgRed($text, $eol = false)
77
 * @method Writer boldGreenBgWhite($text, $eol = false)
78
 * @method Writer boldGreenBgYellow($text, $eol = false)
79
 * @method Writer boldPurple($text, $eol = false)
80
 * @method Writer boldPurpleBgBlack($text, $eol = false)
81
 * @method Writer boldPurpleBgBlue($text, $eol = false)
82
 * @method Writer boldPurpleBgCyan($text, $eol = false)
83
 * @method Writer boldPurpleBgGreen($text, $eol = false)
84
 * @method Writer boldPurpleBgRed($text, $eol = false)
85
 * @method Writer boldPurpleBgWhite($text, $eol = false)
86
 * @method Writer boldPurpleBgYellow($text, $eol = false)
87
 * @method Writer boldRed($text, $eol = false)
88
 * @method Writer boldRedBgBlack($text, $eol = false)
89
 * @method Writer boldRedBgBlue($text, $eol = false)
90
 * @method Writer boldRedBgCyan($text, $eol = false)
91
 * @method Writer boldRedBgGreen($text, $eol = false)
92
 * @method Writer boldRedBgPurple($text, $eol = false)
93
 * @method Writer boldRedBgWhite($text, $eol = false)
94
 * @method Writer boldRedBgYellow($text, $eol = false)
95
 * @method Writer boldWhite($text, $eol = false)
96
 * @method Writer boldWhiteBgBlack($text, $eol = false)
97
 * @method Writer boldWhiteBgBlue($text, $eol = false)
98
 * @method Writer boldWhiteBgCyan($text, $eol = false)
99
 * @method Writer boldWhiteBgGreen($text, $eol = false)
100
 * @method Writer boldWhiteBgPurple($text, $eol = false)
101
 * @method Writer boldWhiteBgRed($text, $eol = false)
102
 * @method Writer boldWhiteBgYellow($text, $eol = false)
103
 * @method Writer boldYellow($text, $eol = false)
104
 * @method Writer boldYellowBgBlack($text, $eol = false)
105
 * @method Writer boldYellowBgBlue($text, $eol = false)
106
 * @method Writer boldYellowBgCyan($text, $eol = false)
107
 * @method Writer boldYellowBgGreen($text, $eol = false)
108
 * @method Writer boldYellowBgPurple($text, $eol = false)
109
 * @method Writer boldYellowBgRed($text, $eol = false)
110
 * @method Writer boldYellowBgWhite($text, $eol = false)
111
 * @method Writer colors($text)
112
 * @method Writer comment($text, $eol = false)
113
 * @method Writer cyan($text, $eol = false)
114
 * @method Writer cyanBgBlack($text, $eol = false)
115
 * @method Writer cyanBgBlue($text, $eol = false)
116
 * @method Writer cyanBgGreen($text, $eol = false)
117
 * @method Writer cyanBgPurple($text, $eol = false)
118
 * @method Writer cyanBgRed($text, $eol = false)
119
 * @method Writer cyanBgWhite($text, $eol = false)
120
 * @method Writer cyanBgYellow($text, $eol = false)
121
 * @method Writer error($text, $eol = false)
122
 * @method Writer green($text, $eol = false)
123
 * @method Writer greenBgBlack($text, $eol = false)
124
 * @method Writer greenBgBlue($text, $eol = false)
125
 * @method Writer greenBgCyan($text, $eol = false)
126
 * @method Writer greenBgPurple($text, $eol = false)
127
 * @method Writer greenBgRed($text, $eol = false)
128
 * @method Writer greenBgWhite($text, $eol = false)
129
 * @method Writer greenBgYellow($text, $eol = false)
130
 * @method Writer info($text, $eol = false)
131
 * @method Writer ok($text, $eol = false)
132
 * @method Writer purple($text, $eol = false)
133
 * @method Writer purpleBgBlack($text, $eol = false)
134
 * @method Writer purpleBgBlue($text, $eol = false)
135
 * @method Writer purpleBgCyan($text, $eol = false)
136
 * @method Writer purpleBgGreen($text, $eol = false)
137
 * @method Writer purpleBgRed($text, $eol = false)
138
 * @method Writer purpleBgWhite($text, $eol = false)
139
 * @method Writer purpleBgYellow($text, $eol = false)
140
 * @method Writer red($text, $eol = false)
141
 * @method Writer redBgBlack($text, $eol = false)
142
 * @method Writer redBgBlue($text, $eol = false)
143
 * @method Writer redBgCyan($text, $eol = false)
144
 * @method Writer redBgGreen($text, $eol = false)
145
 * @method Writer redBgPurple($text, $eol = false)
146
 * @method Writer redBgWhite($text, $eol = false)
147
 * @method Writer redBgYellow($text, $eol = false)
148
 * @method Writer warn($text, $eol = false)
149
 * @method Writer white($text, $eol = false)
150
 * @method Writer yellow($text, $eol = false)
151
 * @method Writer yellowBgBlack($text, $eol = false)
152
 * @method Writer yellowBgBlue($text, $eol = false)
153
 * @method Writer yellowBgCyan($text, $eol = false)
154
 * @method Writer yellowBgGreen($text, $eol = false)
155
 * @method Writer yellowBgPurple($text, $eol = false)
156
 * @method Writer yellowBgRed($text, $eol = false)
157
 * @method Writer yellowBgWhite($text, $eol = false)
158
 */
159
class Writer
160
{
161
    /** @var resource Output file handle */
162
    protected $stream;
163
164
    /** @var resource Error output file handle */
165
    protected $eStream;
166
167
    /** @var string Write method to be relayed to Colorizer */
168
    protected $method;
169
170
    /** @var Color */
171
    protected $colorizer;
172
173
    /** @var Cursor */
174
    protected $cursor;
175
176
    public function __construct(string $path = null, Color $colorizer = null)
177
    {
178
        if ($path) {
179
            $path = \fopen($path, 'w');
180
        }
181
182
        $this->stream  = $path ?: \STDOUT;
0 ignored issues
show
Documentation Bug introduced by
It seems like $path ?: STDOUT can also be of type string. However, the property $stream is declared as type resource. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
183
        $this->eStream = $path ?: \STDERR;
0 ignored issues
show
Documentation Bug introduced by
It seems like $path ?: STDERR can also be of type string. However, the property $eStream is declared as type resource. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
184
185
        $this->cursor    = new Cursor;
186
        $this->colorizer = $colorizer ?? new Color;
187
    }
188
189
    /**
190
     * Get Colorizer.
191
     *
192
     * @return Color
193
     */
194
    public function colorizer(): Color
195
    {
196
        return $this->colorizer;
197
    }
198
199
    /**
200
     * Magically set methods.
201
     *
202
     * @param string $name Like `red`, `bgRed`, 'bold', `error` etc
203
     *
204
     * @return self
205
     */
206
    public function __get(string $name): self
207
    {
208
        if (\strpos($this->method, $name) === false) {
209
            $this->method .= $this->method ? \ucfirst($name) : $name;
210
        }
211
212
        return $this;
213
    }
214
215
    /**
216
     * Write the formatted text to stdout or stderr.
217
     *
218
     * @param string $text
219
     * @param bool   $eol
220
     *
221
     * @return self
222
     */
223
    public function write(string $text, bool $eol = false): self
224
    {
225
        list($method, $this->method) = [$this->method ?: 'line', ''];
226
227
        $text  = $this->colorizer->{$method}($text, []);
228
        $error = \stripos($method, 'error') !== false;
229
230
        if ($eol) {
231
            $text .= \PHP_EOL;
232
        }
233
234
        return $this->doWrite($text, $error);
235
    }
236
237
    /**
238
     * Really write to the stream.
239
     *
240
     * @param string $text
241
     * @param bool   $error
242
     *
243
     * @return self
244
     */
245
    protected function doWrite(string $text, bool $error = false): self
246
    {
247
        $stream = $error ? $this->eStream : $this->stream;
248
249
        \fwrite($stream, $text);
250
251
        return $this;
252
    }
253
254
    /**
255
     * Write EOL n times.
256
     *
257
     * @param int $n
258
     *
259
     * @return self
260
     */
261
    public function eol(int $n = 1): self
262
    {
263
        return $this->doWrite(\str_repeat(PHP_EOL, \max($n, 1)));
264
    }
265
266
    /**
267
     * Write raw text (as it is).
268
     *
269
     * @param string $text
270
     * @param bool   $error
271
     *
272
     * @return self
273
     */
274
    public function raw($text, bool $error = false): self
275
    {
276
        return $this->doWrite((string) $text, $error);
277
    }
278
279
    /**
280
     * Generate table for the console. Keys of first row are taken as header.
281
     *
282
     * @param array[] $rows   Array of assoc arrays.
283
     * @param array   $styles Eg: ['head' => 'bold', 'odd' => 'comment', 'even' => 'green']
284
     *
285
     * @return self
286
     */
287
    public function table(array $rows, array $styles = []): self
288
    {
289
        $table = (new Table)->render($rows, $styles);
290
291
        return $this->colors($table);
292
    }
293
294
    /**
295
     * Write to stdout or stderr magically.
296
     *
297
     * @param string $method
298
     * @param array  $arguments
299
     *
300
     * @return self
301
     */
302
    public function __call(string $method, array $arguments): self
303
    {
304
        if (\method_exists($this->cursor, $method)) {
305
            return $this->doWrite($this->cursor->{$method}(...$arguments));
306
        }
307
308
        $this->method = $method;
309
310
        return $this->write(...$arguments);
0 ignored issues
show
Bug introduced by
$arguments is expanded, but the parameter $text of Ahc\Cli\Output\Writer::write() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

310
        return $this->write(/** @scrutinizer ignore-type */ ...$arguments);
Loading history...
311
    }
312
}
313