Completed
Pull Request — master (#103)
by
unknown
02:11
created

MenuStyle::getDisabledItemText()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 1
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
     * Default Values
78
     *
79
     * @var array
80
     */
81
    private static $defaultStyleValues = [
82
        'fg' => 'white',
83
        'bg' => 'blue',
84
        'width' => 100,
85
        'padding' => 2,
86
        'margin' => 2,
87
        'selectedMarker' => '●',
88
        'unselectedMarker' => '○',
89
        'itemExtra' => '✔',
90
        'displaysExtra' => false,
91
        'titleSeparator' => '=',
92
    ];
93
94
    public static function getDefaultStyleValues() : array
95
    {
96
        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...
97
    }
98
99
    /**
100
     * @var array
101
     */
102
    private static $availableForegroundColors = array(
103
        'black'   => array('set' => 30, 'unset' => 39),
104
        'red'     => array('set' => 31, 'unset' => 39),
105
        'green'   => array('set' => 32, 'unset' => 39),
106
        'yellow'  => array('set' => 33, 'unset' => 39),
107
        'blue'    => array('set' => 34, 'unset' => 39),
108
        'magenta' => array('set' => 35, 'unset' => 39),
109
        'cyan'    => array('set' => 36, 'unset' => 39),
110
        'white'   => array('set' => 37, 'unset' => 39),
111
        'default' => array('set' => 39, 'unset' => 39),
112
    );
113
114
    /**
115
     * @var array
116
     */
117
    private static $availableBackgroundColors = array(
118
        'black'   => array('set' => 40, 'unset' => 49),
119
        'red'     => array('set' => 41, 'unset' => 49),
120
        'green'   => array('set' => 42, 'unset' => 49),
121
        'yellow'  => array('set' => 43, 'unset' => 49),
122
        'blue'    => array('set' => 44, 'unset' => 49),
123
        'magenta' => array('set' => 45, 'unset' => 49),
124
        'cyan'    => array('set' => 46, 'unset' => 49),
125
        'white'   => array('set' => 47, 'unset' => 49),
126
        'default' => array('set' => 49, 'unset' => 49),
127
    );
128
129
    /**
130
     * @var array
131
     */
132
    private static $availableOptions = array(
133
        'bold'       => array('set' => 1, 'unset' => 22),
134
        'dim'        => array('set' => 2, 'unset' => 22),
135
        'underscore' => array('set' => 4, 'unset' => 24),
136
        'blink'      => array('set' => 5, 'unset' => 25),
137
        'reverse'    => array('set' => 7, 'unset' => 27),
138
        'conceal'    => array('set' => 8, 'unset' => 28)
139
    );
140
141
    /**
142
     * Initialise style
143
     */
144
    public function __construct(Terminal $terminal = null)
145
    {
146
        $this->terminal = $terminal ?: TerminalFactory::fromSystem();
147
148
        $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...
149
        $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...
150
        $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...
151
        $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...
152
        $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...
153
        $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...
154
        $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...
155
        $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...
156
        $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...
157
        $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...
158
    }
159
160
    public static function getAvailableColours() : array
161
    {
162
        return array_keys(self::$availableBackgroundColors);
163
    }
164
165
    public function getDisabledItemText(string $text) : string
166
    {
167
        return sprintf(
168
            "\033[%sm%s\033[%sm",
169
            self::$availableOptions['dim']['set'],
170
            $text,
171
            self::$availableOptions['dim']['unset']
172
        );
173
    }
174
    
175
    /**
176
     * Get the colour code set for Bg and Fg
177
     */
178 View Code Duplication
    public function getSelectedSetCode() : string
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...
179
    {
180
        return sprintf(
181
            "\033[%sm",
182
            implode(';', [
183
                self::$availableBackgroundColors[$this->getFg()]['set'],
184
                self::$availableForegroundColors[$this->getBg()]['set'],
185
            ])
186
        );
187
    }
188
189
    /**
190
     * Get the colour unset code for Bg and Fg
191
     */
192 View Code Duplication
    public function getSelectedUnsetCode() : string
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...
193
    {
194
        return sprintf(
195
            "\033[%sm",
196
            implode(';', [
197
                self::$availableBackgroundColors[$this->getBg()]['unset'],
198
                self::$availableForegroundColors[$this->getFg()]['unset'],
199
            ])
200
        );
201
    }
202
203
    /**
204
     * Get the inverted colour code
205
     */
206 View Code Duplication
    public function getUnselectedSetCode() : string
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...
207
    {
208
        return sprintf(
209
            "\033[%sm",
210
            implode(';', [
211
                self::$availableBackgroundColors[$this->getBg()]['set'],
212
                self::$availableForegroundColors[$this->getFg()]['set'],
213
            ])
214
        );
215
    }
216
217
    /**
218
     * Get the inverted colour unset code
219
     */
220 View Code Duplication
    public function getUnselectedUnsetCode() : string
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...
221
    {
222
        return sprintf(
223
            "\033[%sm",
224
            implode(';', [
225
                self::$availableBackgroundColors[$this->getBg()]['unset'],
226
                self::$availableForegroundColors[$this->getFg()]['unset'],
227
            ])
228
        );
229
    }
230
231
    /**
232
     * Calculate the contents width
233
     */
234
    protected function calculateContentWidth() : void
235
    {
236
        $this->contentWidth = $this->width - ($this->padding*2);
237
    }
238
239
    public function getFg() : string
240
    {
241
        return $this->fg;
242
    }
243
244
    public function setFg(string $fg) : self
245
    {
246
        $this->fg = $fg;
247
248
        return $this;
249
    }
250
251
    public function getBg() : string
252
    {
253
        return $this->bg;
254
    }
255
256
    public function setBg(string $bg) : self
257
    {
258
        $this->bg = $bg;
259
260
        return $this;
261
    }
262
263
    public function getWidth() : int
264
    {
265
        return $this->width;
266
    }
267
268
    public function setWidth(int $width) : self
269
    {
270
        if ($width >= $this->terminal->getWidth()) {
271
            $width = $this->terminal->getWidth();
272
        }
273
274
        $this->width = $width;
275
        if ($this->margin === -1) {
276
            $this->setMargin(-1);
277
        }
278
        $this->calculateContentWidth();
279
280
        return $this;
281
    }
282
283
    public function getPadding() : int
284
    {
285
        return $this->padding;
286
    }
287
288
    public function setPadding(int $padding) : self
289
    {
290
        $this->padding = $padding;
291
292
        $this->calculateContentWidth();
293
294
        return $this;
295
    }
296
297
    public function getMargin() : int
298
    {
299
        return $this->margin;
300
    }
301
302
    public function setMargin(int $margin) : self
303
    {
304
        if ($margin === -1) {
305
            $this->margin = floor(($this->terminal->getWidth() - $this->width) / 2);
0 ignored issues
show
Documentation Bug introduced by
The property $margin was declared of type integer, but floor(($this->terminal->...() - $this->width) / 2) is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
306
        } else {
307
            $this->margin = $margin;
308
        }
309
310
        return $this;
311
    }
312
313
    public function getContentWidth() : int
314
    {
315
        return $this->contentWidth;
316
    }
317
318
    /**
319
     * Get padding for right had side of content
320
     */
321
    public function getRightHandPadding(int $contentLength) : int
322
    {
323
        return $this->getContentWidth() - $contentLength + $this->getPadding();
324
    }
325
326
    public function getSelectedMarker() : string
327
    {
328
        return $this->selectedMarker;
329
    }
330
331
    public function setSelectedMarker(string $marker) : self
332
    {
333
        $this->selectedMarker = mb_substr($marker, 0, 1);
334
335
        return $this;
336
    }
337
338
    public function getUnselectedMarker() : string
339
    {
340
        return $this->unselectedMarker;
341
    }
342
343
    public function setUnselectedMarker(string $marker) : self
344
    {
345
        $this->unselectedMarker = mb_substr($marker, 0, 1);
346
347
        return $this;
348
    }
349
350
    /**
351
     * Get the correct marker for the item
352
     */
353
    public function getMarker(bool $selected) : string
354
    {
355
        return $selected ? $this->selectedMarker : $this->unselectedMarker;
356
    }
357
358
    public function setItemExtra(string $itemExtra) : self
359
    {
360
        $this->itemExtra = $itemExtra;
361
362
        return $this;
363
    }
364
365
    public function getItemExtra() : string
366
    {
367
        return $this->itemExtra;
368
    }
369
370
    public function getDisplaysExtra() : bool
371
    {
372
        return $this->displaysExtra;
373
    }
374
375
    public function setDisplaysExtra(bool $displaysExtra) : self
376
    {
377
        $this->displaysExtra = $displaysExtra;
378
379
        return $this;
380
    }
381
382
    public function getTitleSeparator() : string
383
    {
384
        return $this->titleSeparator;
385
    }
386
387
    public function setTitleSeparator(string $actionSeparator) : self
388
    {
389
        $this->titleSeparator = $actionSeparator;
390
391
        return $this;
392
    }
393
}
394