Completed
Pull Request — master (#104)
by
unknown
01:59 queued 14s
created

MenuStyle::getBg()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace PhpSchool\CliMenu;
4
5
use PhpSchool\CliMenu\Exception\InvalidInstantiationException;
6
use PhpSchool\CliMenu\Terminal\TerminalFactory;
7
use PhpSchool\Terminal\Terminal;
8
9
//TODO: B/W fallback
10
11
/**
12
 * @author Michael Woodward <[email protected]>
13
 */
14
class MenuStyle
15
{
16
    /**
17
     * @var Terminal
18
     */
19
    protected $terminal;
20
21
    /**
22
     * @var string
23
     */
24
    protected $fg;
25
26
    /**
27
     * @var string
28
     */
29
    protected $bg;
30
31
    /**
32
     * @var int
33
     */
34
    protected $width;
35
36
    /**
37
     * @var int
38
     */
39
    protected $padding;
40
41
    /**
42
     * @var int
43
     */
44
    protected $margin;
45
46
    /**
47
     * @var int
48
     */
49
    protected $contentWidth;
50
51
    /**
52
     * @var string
53
     */
54
    private $selectedMarker;
55
56
    /**
57
     * @var string
58
     */
59
    private $unselectedMarker;
60
61
    /**
62
     * @var string
63
     */
64
    private $itemExtra;
65
66
    /**
67
     * @var bool
68
     */
69
    private $displaysExtra;
70
71
    /**
72
     * @var string
73
     */
74
    private $titleSeparator;
75
76
    /**
77
     * @var string
78
     */
79
    private $coloursSetCode;
80
81
    /**
82
     * @var string
83
     */
84
    private $invertedColoursSetCode = "\033[7m";
85
86
    /**
87
     * @var string
88
     */
89
    private $invertedColoursUnsetCode = "\033[27m";
90
91
    /**
92
     * @var string
93
     */
94
    private $coloursResetCode = "\033[0m";
95
96
    /**
97
     * Default Values
98
     *
99
     * @var array
100
     */
101
    private static $defaultStyleValues = [
102
        'fg' => 'white',
103
        'bg' => 'blue',
104
        'width' => 100,
105
        'padding' => 2,
106
        'margin' => 2,
107
        'selectedMarker' => '●',
108
        'unselectedMarker' => '○',
109
        'itemExtra' => '✔',
110
        'displaysExtra' => false,
111
        'titleSeparator' => '=',
112
    ];
113
114
    public static function getDefaultStyleValues() : array
115
    {
116
        return static::$defaultStyleValues;
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
117
    }
118
119
    /**
120
     * @var array
121
     */
122
    private static $availableForegroundColors = array(
123
        'black'   => 30,
124
        'red'     => 31,
125
        'green'   => 32,
126
        'yellow'  => 33,
127
        'blue'    => 34,
128
        'magenta' => 35,
129
        'cyan'    => 36,
130
        'white'   => 37,
131
        'default' => 39,
132
    );
133
134
    /**
135
     * @var array
136
     */
137
    private static $availableBackgroundColors = array(
138
        'black'   => 40,
139
        'red'     => 41,
140
        'green'   => 42,
141
        'yellow'  => 43,
142
        'blue'    => 44,
143
        'magenta' => 45,
144
        'cyan'    => 46,
145
        'white'   => 47,
146
        'default' => 49,
147
    );
148
149
    /**
150
     * @var array
151
     */
152
    private static $availableOptions = array(
153
        'bold'       => array('set' => 1, 'unset' => 22),
154
        'dim'        => array('set' => 2, 'unset' => 22),
155
        'underscore' => array('set' => 4, 'unset' => 24),
156
        'blink'      => array('set' => 5, 'unset' => 25),
157
        'reverse'    => array('set' => 7, 'unset' => 27),
158
        'conceal'    => array('set' => 8, 'unset' => 28)
159
    );
160
161
    /**
162
     * Initialise style
163
     */
164
    public function __construct(Terminal $terminal = null)
165
    {
166
        $this->terminal = $terminal ?: TerminalFactory::fromSystem();
167
168
        $this->setFg(static::$defaultStyleValues['fg']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
169
        $this->setBg(static::$defaultStyleValues['bg']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
170
        $this->setWidth(static::$defaultStyleValues['width']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
171
        $this->setPadding(static::$defaultStyleValues['padding']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
172
        $this->setMargin(static::$defaultStyleValues['margin']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
173
        $this->setSelectedMarker(static::$defaultStyleValues['selectedMarker']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
174
        $this->setUnselectedMarker(static::$defaultStyleValues['unselectedMarker']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
175
        $this->setItemExtra(static::$defaultStyleValues['itemExtra']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
176
        $this->setDisplaysExtra(static::$defaultStyleValues['displaysExtra']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
177
        $this->setTitleSeparator(static::$defaultStyleValues['titleSeparator']);
0 ignored issues
show
Bug introduced by
Since $defaultStyleValues is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $defaultStyleValues to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
178
    }
179
180
    public static function getAvailableColours() : array
181
    {
182
        return array_keys(self::$availableBackgroundColors);
183
    }
184
185
    public function getDisabledItemText(string $text) : string
186
    {
187
        return sprintf(
188
            "\033[%sm%s\033[%sm",
189
            self::$availableOptions['dim']['set'],
190
            $text,
191
            self::$availableOptions['dim']['unset']
192
        );
193
    }
194
195
    /**
196
     * Generates the ansi escape sequence to set the colours
197
     */
198
    private function generateColoursSetCode() : void
199
    {
200
        if (is_string($this->fg)) {
201
            $fgCode = self::$availableForegroundColors[$this->fg];
202
        } else {
203
            $fgCode = sprintf("38;5;%s", $this->fg);
204
        }
205
206
        if (is_string($this->bg)) {
207
            $bgCode = self::$availableBackgroundColors[$this->bg];
208
        } else {
209
            $bgCode = sprintf("48;5;%s", $this->bg);
210
        }
211
212
        $this->coloursSetCode = sprintf("\033[%s;%sm", $fgCode, $bgCode);
213
    }
214
215
    /**
216
     * Get the colour code for Bg and Fg
217
     */
218
    public function getColoursSetCode() : string
219
    {
220
        return $this->coloursSetCode;
221
    }
222
223
    /**
224
     * Get the inverted escape sequence (used for selected elements)
225
     */
226
    public function getInvertedColoursSetCode() : string
227
    {
228
        return $this->invertedColoursSetCode;
229
    }
230
231
    /**
232
     * Get the inverted escape sequence (used for selected elements)
233
     */
234
    public function getInvertedColoursUnsetCode() : string
235
    {
236
        return $this->invertedColoursUnsetCode;
237
    }
238
239
    /**
240
     * Get the escape sequence used to reset colours to default
241
     */
242
    public function getColoursResetCode() : string
243
    {
244
        return $this->coloursResetCode;
245
    }
246
247
    /**
248
     * Calculate the contents width
249
     */
250
    protected function calculateContentWidth() : void
251
    {
252
        $this->contentWidth = $this->width - ($this->padding*2) - ($this->margin*2);
253
    }
254
255
    public function getFg() : string
256
    {
257
        return $this->fg;
258
    }
259
260 View Code Duplication
    public function setFg($fg, string $fallback = null) : self
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
261
    {
262
        if (is_int($fg)) {
263
            if ($this->terminal->getColourSupport() < 256) {
264
                $fg = $fallback;
265
            } elseif ($fg < 0 || $fg > 255) {
266
                throw new \Exception("Invalid colour code");
267
            }
268
        }
269
270
        $this->fg = $fg;
271
        $this->generateColoursSetCode();
272
273
        return $this;
274
    }
275
276
    public function getBg() : string
277
    {
278
        return $this->bg;
279
    }
280
281 View Code Duplication
    public function setBg($bg, string $fallback = null) : self
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
282
    {
283
        if (is_int($bg)) {
284
            if ($this->terminal->getColourSupport() < 256) {
285
                $bg = $fallback;
286
            } elseif ($bg < 0 || $bg > 255) {
287
                throw new \Exception("Invalid colour code");
288
            }
289
        }
290
        $this->bg = $bg;
291
        $this->generateColoursSetCode();
292
293
        return $this;
294
    }
295
296
    public function getWidth() : int
297
    {
298
        return $this->width;
299
    }
300
301
    public function setWidth(int $width) : self
302
    {
303
        $availableWidth = $this->terminal->getWidth() - ($this->margin * 2) - ($this->padding * 2);
304
305
        if ($width >= $availableWidth) {
306
            $width = $availableWidth;
307
        }
308
309
        $this->width = $width;
0 ignored issues
show
Documentation Bug introduced by
It seems like $width can also be of type double. However, the property $width is declared as type integer. 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...
310
        $this->calculateContentWidth();
311
312
        return $this;
313
    }
314
315
    public function getPadding() : int
316
    {
317
        return $this->padding;
318
    }
319
320
    public function setPadding(int $padding) : self
321
    {
322
        $this->padding = $padding;
323
324
        $this->calculateContentWidth();
325
326
        return $this;
327
    }
328
329
    public function getMargin() : int
330
    {
331
        return $this->margin;
332
    }
333
334
    public function setMargin(int $margin) : self
335
    {
336
        $this->margin = $margin;
337
338
        $this->calculateContentWidth();
339
340
        return $this;
341
    }
342
343
    public function getContentWidth() : int
344
    {
345
        return $this->contentWidth;
346
    }
347
348
    /**
349
     * Get padding for right had side of content
350
     */
351
    public function getRightHandPadding(int $contentLength) : int
352
    {
353
        return $this->getContentWidth() - $contentLength + $this->getPadding();
354
    }
355
356
    public function getSelectedMarker() : string
357
    {
358
        return $this->selectedMarker;
359
    }
360
361
    public function setSelectedMarker(string $marker) : self
362
    {
363
        $this->selectedMarker = mb_substr($marker, 0, 1);
364
365
        return $this;
366
    }
367
368
    public function getUnselectedMarker() : string
369
    {
370
        return $this->unselectedMarker;
371
    }
372
373
    public function setUnselectedMarker(string $marker) : self
374
    {
375
        $this->unselectedMarker = mb_substr($marker, 0, 1);
376
377
        return $this;
378
    }
379
380
    /**
381
     * Get the correct marker for the item
382
     */
383
    public function getMarker(bool $selected) : string
384
    {
385
        return $selected ? $this->selectedMarker : $this->unselectedMarker;
386
    }
387
388
    public function setItemExtra(string $itemExtra) : self
389
    {
390
        $this->itemExtra = $itemExtra;
391
392
        return $this;
393
    }
394
395
    public function getItemExtra() : string
396
    {
397
        return $this->itemExtra;
398
    }
399
400
    public function getDisplaysExtra() : bool
401
    {
402
        return $this->displaysExtra;
403
    }
404
405
    public function setDisplaysExtra(bool $displaysExtra) : self
406
    {
407
        $this->displaysExtra = $displaysExtra;
408
409
        return $this;
410
    }
411
412
    public function getTitleSeparator() : string
413
    {
414
        return $this->titleSeparator;
415
    }
416
417
    public function setTitleSeparator(string $actionSeparator) : self
418
    {
419
        $this->titleSeparator = $actionSeparator;
420
421
        return $this;
422
    }
423
}
424