Completed
Pull Request — master (#121)
by
unknown
02:06
created

MenuStyle::getItemExtra()   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\CliMenu\Util\ColourUtil;
8
use PhpSchool\Terminal\Terminal;
9
use Assert\Assertion;
10
11
//TODO: B/W fallback
12
13
/**
14
 * @author Michael Woodward <[email protected]>
15
 */
16
class MenuStyle
17
{
18
    /**
19
     * @var Terminal
20
     */
21
    protected $terminal;
22
23
    /**
24
     * @var string
25
     */
26
    protected $fg;
27
28
    /**
29
     * @var string
30
     */
31
    protected $bg;
32
33
    /**
34
     * @var int
35
     */
36
    protected $width;
37
38
    /**
39
     * @var int
40
     */
41
    protected $margin;
42
43
    /**
44
     * @var int
45
     */
46
    protected $paddingTopBottom;
47
48
    /**
49
     * @var int
50
     */
51
    protected $paddingLeftRight;
52
53
    /**
54
     * @var array
55
     */
56
    private $paddingTopBottomRows = [];
57
58
    /**
59
     * @var int
60
     */
61
    protected $contentWidth;
62
63
    /**
64
     * @var string
65
     */
66
    private $selectedMarker;
67
68
    /**
69
     * @var string
70
     */
71
    private $unselectedMarker;
72
73
    /**
74
     * @var string
75
     */
76
    private $itemExtra;
77
78
    /**
79
     * @var bool
80
     */
81
    private $displaysExtra;
82
83
    /**
84
     * @var string
85
     */
86
    private $titleSeparator;
87
88
    /**
89
     * @var string
90
     */
91
    private $coloursSetCode;
92
93
    /**
94
     * @var string
95
     */
96
    private $invertedColoursSetCode = "\033[7m";
97
98
    /**
99
     * @var string
100
     */
101
    private $invertedColoursUnsetCode = "\033[27m";
102
103
    /**
104
     * @var string
105
     */
106
    private $coloursResetCode = "\033[0m";
107
108
    /**
109
     * @var int
110
     */
111
    private $borderTopWidth;
112
113
    /**
114
     * @var int
115
     */
116
    private $borderRightWidth;
117
118
    /**
119
     * @var int
120
     */
121
    private $borderBottomWidth;
122
123
    /**
124
     * @var int
125
     */
126
    private $borderLeftWidth;
127
128
    /**
129
     * @var string
130
     */
131
    private $borderColour = 'white';
132
133
    /**
134
     * @var array
135
     */
136
    private $borderTopRows = [];
137
138
    /**
139
     * @var array
140
     */
141
    private $borderBottomRows = [];
142
143
    /**
144
     * @var bool
145
     */
146
    private $marginAuto = false;
147
148
    /**
149
     * Default Values
150
     *
151
     * @var array
152
     */
153
    private static $defaultStyleValues = [
154
        'fg' => 'white',
155
        'bg' => 'blue',
156
        'width' => 100,
157
        'paddingTopBottom' => 1,
158
        'paddingLeftRight' => 2,
159
        'margin' => 2,
160
        'selectedMarker' => '●',
161
        'unselectedMarker' => '○',
162
        'itemExtra' => '✔',
163
        'displaysExtra' => false,
164
        'titleSeparator' => '=',
165
        'borderTopWidth' => 0,
166
        'borderRightWidth' => 0,
167
        'borderBottomWidth' => 0,
168
        'borderLeftWidth' => 0,
169
        'borderColour' => 'white',
170
        'marginAuto' => false,
171
    ];
172
173
    public static function getDefaultStyleValues() : array
174
    {
175
        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...
176
    }
177
178
    /**
179
     * @var array
180
     */
181
    private static $availableForegroundColors = array(
182
        'black'   => 30,
183
        'red'     => 31,
184
        'green'   => 32,
185
        'yellow'  => 33,
186
        'blue'    => 34,
187
        'magenta' => 35,
188
        'cyan'    => 36,
189
        'white'   => 37,
190
        'default' => 39,
191
    );
192
193
    /**
194
     * @var array
195
     */
196
    private static $availableBackgroundColors = array(
197
        'black'   => 40,
198
        'red'     => 41,
199
        'green'   => 42,
200
        'yellow'  => 43,
201
        'blue'    => 44,
202
        'magenta' => 45,
203
        'cyan'    => 46,
204
        'white'   => 47,
205
        'default' => 49,
206
    );
207
208
    /**
209
     * @var array
210
     */
211
    private static $availableOptions = array(
212
        'bold'       => array('set' => 1, 'unset' => 22),
213
        'dim'        => array('set' => 2, 'unset' => 22),
214
        'underscore' => array('set' => 4, 'unset' => 24),
215
        'blink'      => array('set' => 5, 'unset' => 25),
216
        'reverse'    => array('set' => 7, 'unset' => 27),
217
        'conceal'    => array('set' => 8, 'unset' => 28)
218
    );
219
220
    /**
221
     * Initialise style
222
     */
223
    public function __construct(Terminal $terminal = null)
224
    {
225
        $this->terminal = $terminal ?: TerminalFactory::fromSystem();
226
227
        $this->fg = 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...
228
        $this->bg = 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...
229
230
        $this->generateColoursSetCode();
231
232
        $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...
233
        $this->setPaddingTopBottom(static::$defaultStyleValues['paddingTopBottom']);
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...
234
        $this->setPaddingLeftRight(static::$defaultStyleValues['paddingLeftRight']);
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...
235
        $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...
236
        $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...
237
        $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...
238
        $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...
239
        $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...
240
        $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...
241
        $this->setBorderTopWidth(static::$defaultStyleValues['borderTopWidth']);
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...
242
        $this->setBorderRightWidth(static::$defaultStyleValues['borderRightWidth']);
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...
243
        $this->setBorderBottomWidth(static::$defaultStyleValues['borderBottomWidth']);
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...
244
        $this->setBorderLeftWidth(static::$defaultStyleValues['borderLeftWidth']);
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...
245
        $this->setBorderColour(static::$defaultStyleValues['borderColour']);
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...
246
    }
247
248
    public function getDisabledItemText(string $text) : string
249
    {
250
        return sprintf(
251
            "\033[%sm%s\033[%sm",
252
            self::$availableOptions['dim']['set'],
253
            $text,
254
            self::$availableOptions['dim']['unset']
255
        );
256
    }
257
258
    /**
259
     * Generates the ansi escape sequence to set the colours
260
     */
261
    private function generateColoursSetCode() : void
262
    {
263
        if (!ctype_digit($this->fg)) {
264
            $fgCode = self::$availableForegroundColors[$this->fg];
265
        } else {
266
            $fgCode = sprintf("38;5;%s", $this->fg);
267
        }
268
269
        if (!ctype_digit($this->bg)) {
270
            $bgCode = self::$availableBackgroundColors[$this->bg];
271
        } else {
272
            $bgCode = sprintf("48;5;%s", $this->bg);
273
        }
274
275
        $this->coloursSetCode = sprintf("\033[%s;%sm", $fgCode, $bgCode);
276
    }
277
278
    /**
279
     * Get the colour code for Bg and Fg
280
     */
281
    public function getColoursSetCode() : string
282
    {
283
        return $this->coloursSetCode;
284
    }
285
286
    /**
287
     * Get the inverted escape sequence (used for selected elements)
288
     */
289
    public function getInvertedColoursSetCode() : string
290
    {
291
        return $this->invertedColoursSetCode;
292
    }
293
294
    /**
295
     * Get the inverted escape sequence (used for selected elements)
296
     */
297
    public function getInvertedColoursUnsetCode() : string
298
    {
299
        return $this->invertedColoursUnsetCode;
300
    }
301
302
    /**
303
     * Get the escape sequence used to reset colours to default
304
     */
305
    public function getColoursResetCode() : string
306
    {
307
        return $this->coloursResetCode;
308
    }
309
310
    /**
311
     * Calculate the contents width
312
     */
313
    protected function calculateContentWidth() : void
314
    {
315
        $this->contentWidth = $this->width
316
            - ($this->paddingLeftRight * 2)
317
            - ($this->borderRightWidth + $this->borderLeftWidth);
318
    }
319
320
    public function getFg()
321
    {
322
        return $this->fg;
323
    }
324
325 View Code Duplication
    public function setFg(string $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...
326
    {
327
        $this->fg = ColourUtil::validateColour(
328
            $this->terminal,
329
            $fg,
330
            $fallback
331
        );
332
        $this->generateColoursSetCode();
333
334
        return $this;
335
    }
336
337
    public function getBg()
338
    {
339
        return $this->bg;
340
    }
341
342
    public function setBg(string $bg, string $fallback = null) : self
343
    {
344
        $this->bg = ColourUtil::validateColour(
345
            $this->terminal,
346
            $bg,
347
            $fallback
348
        );
349
350
        $this->generateColoursSetCode();
351
        $this->generatePaddingTopBottomRows();
352
353
        return $this;
354
    }
355
356
    public function getWidth() : int
357
    {
358
        return $this->width;
359
    }
360
361
    public function setWidth(int $width) : self
362
    {
363
        Assertion::greaterOrEqualThan($width, 0);
364
365
        if ($width >= $this->terminal->getWidth()) {
366
            $width = $this->terminal->getWidth();
367
        }
368
369
        $this->width = $width;
370
        if ($this->marginAuto) {
371
            $this->setMarginAuto();
372
        }
373
374
        $this->calculateContentWidth();
375
        $this->generateBorderRows();
376
        $this->generatePaddingTopBottomRows();
377
378
        return $this;
379
    }
380
381
    public function getPaddingTopBottom() : int
382
    {
383
        return $this->paddingTopBottom;
384
    }
385
386
    public function getPaddingLeftRight() : int
387
    {
388
        return $this->paddingLeftRight;
389
    }
390
391
    private function generatePaddingTopBottomRows() : void
392
    {
393
        if ($this->borderLeftWidth || $this->borderRightWidth) {
394
            $borderColour = $this->getBorderColourCode();
395
        } else {
396
            $borderColour = '';
397
        }
398
399
        $paddingRow = sprintf(
400
            "%s%s%s%s%s%s%s%s%s%s\n",
401
            str_repeat(' ', $this->margin),
402
            $borderColour,
403
            str_repeat(' ', $this->borderRightWidth),
404
            $this->getColoursSetCode(),
405
            str_repeat(' ', $this->paddingLeftRight),
406
            str_repeat(' ', $this->contentWidth),
407
            str_repeat(' ', $this->paddingLeftRight),
408
            $borderColour,
409
            str_repeat(' ', $this->borderRightWidth),
410
            $this->coloursResetCode
411
        );
412
413
        $this->paddingTopBottomRows = array_fill(0, $this->paddingTopBottom, $paddingRow);
414
    }
415
416
    public function getPaddingTopBottomRows() : array
417
    {
418
        return $this->paddingTopBottomRows;
419
    }
420
421 View Code Duplication
    public function setPadding(int $topBottom, int $leftRight = 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...
422
    {
423
        if ($leftRight === null) {
424
            $leftRight = $topBottom;
425
        }
426
427
        $this->setPaddingTopBottom($topBottom);
428
        $this->setPaddingLeftRight($leftRight);
429
430
        $this->calculateContentWidth();
431
        $this->generatePaddingTopBottomRows();
432
433
        return $this;
434
    }
435
436
    public function setPaddingTopBottom(int $topBottom) : self
437
    {
438
        Assertion::greaterOrEqualThan($topBottom, 0);
439
        $this->paddingTopBottom = $topBottom;
440
441
        $this->generatePaddingTopBottomRows();
442
443
        return $this;
444
    }
445
446
    public function setPaddingLeftRight(int $leftRight) : self
447
    {
448
        Assertion::greaterOrEqualThan($leftRight, 0);
449
        $this->paddingLeftRight = $leftRight;
450
451
        $this->calculateContentWidth();
452
        $this->generatePaddingTopBottomRows();
453
454
        return $this;
455
    }
456
457
    public function getMargin() : int
458
    {
459
        return $this->margin;
460
    }
461
462
    public function setMarginAuto() : self
463
    {
464
        $this->marginAuto = true;
465
        $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...
466
467
        $this->generateBorderRows();
468
        $this->generatePaddingTopBottomRows();
469
470
        return $this;
471
    }
472
473
    public function setMargin(int $margin) : self
474
    {
475
        Assertion::greaterOrEqualThan($margin, 0);
476
477
        $this->marginAuto = false;
478
        $this->margin = $margin;
479
480
        $this->generateBorderRows();
481
        $this->generatePaddingTopBottomRows();
482
483
        return $this;
484
    }
485
486
    public function getContentWidth() : int
487
    {
488
        return $this->contentWidth;
489
    }
490
491
    /**
492
     * Get padding for right had side of content
493
     */
494
    public function getRightHandPadding(int $contentLength) : int
495
    {
496
        $rightPadding = $this->getContentWidth() - $contentLength + $this->getPaddingLeftRight();
497
498
        if ($rightPadding < 0) {
499
            $rightPadding = 0;
500
        }
501
502
        return $rightPadding;
503
    }
504
505
    public function getSelectedMarker() : string
506
    {
507
        return $this->selectedMarker;
508
    }
509
510
    public function setSelectedMarker(string $marker) : self
511
    {
512
        $this->selectedMarker = mb_substr($marker, 0, 1);
513
514
        return $this;
515
    }
516
517
    public function getUnselectedMarker() : string
518
    {
519
        return $this->unselectedMarker;
520
    }
521
522
    public function setUnselectedMarker(string $marker) : self
523
    {
524
        $this->unselectedMarker = mb_substr($marker, 0, 1);
525
526
        return $this;
527
    }
528
529
    /**
530
     * Get the correct marker for the item
531
     */
532
    public function getMarker(bool $selected) : string
533
    {
534
        return $selected ? $this->selectedMarker : $this->unselectedMarker;
535
    }
536
537
    public function setItemExtra(string $itemExtra) : self
538
    {
539
        $this->itemExtra = $itemExtra;
540
541
        return $this;
542
    }
543
544
    public function getItemExtra() : string
545
    {
546
        return $this->itemExtra;
547
    }
548
549
    public function getDisplaysExtra() : bool
550
    {
551
        return $this->displaysExtra;
552
    }
553
554
    public function setDisplaysExtra(bool $displaysExtra) : self
555
    {
556
        $this->displaysExtra = $displaysExtra;
557
558
        return $this;
559
    }
560
561
    public function getTitleSeparator() : string
562
    {
563
        return $this->titleSeparator;
564
    }
565
566
    public function setTitleSeparator(string $actionSeparator) : self
567
    {
568
        $this->titleSeparator = $actionSeparator;
569
570
        return $this;
571
    }
572
573
    private function generateBorderRows() : void
574
    {
575
        $borderRow = sprintf(
576
            "%s%s%s%s\n",
577
            str_repeat(' ', $this->margin),
578
            $this->getBorderColourCode(),
579
            str_repeat(' ', $this->width),
580
            $this->coloursResetCode
581
        );
582
583
        $this->borderTopRows = array_fill(0, $this->borderTopWidth, $borderRow);
584
        $this->borderBottomRows = array_fill(0, $this->borderBottomWidth, $borderRow);
585
    }
586
587
    public function getBorderTopRows() : array
588
    {
589
        return $this->borderTopRows;
590
    }
591
592
    public function getBorderBottomRows() : array
593
    {
594
        return $this->borderBottomRows;
595
    }
596
597
    /**
598
     * Shorthand function to set all borders values at once
599
     */
600
    public function setBorder(
601
        int $topWidth,
602
        $rightWidth = null,
603
        $bottomWidth = null,
604
        $leftWidth = null,
605
        string $colour = null
606
    ) : self {
607 View Code Duplication
        if (!is_int($rightWidth)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
608
            $colour = $rightWidth;
609
            $rightWidth = $bottomWidth = $leftWidth = $topWidth;
610
        } elseif (!is_int($bottomWidth)) {
611
            $colour = $bottomWidth;
612
            $bottomWidth = $topWidth;
613
            $leftWidth = $rightWidth;
614
        } elseif (!is_int($leftWidth)) {
615
            $colour = $leftWidth;
616
            $leftWidth = $rightWidth;
617
        }
618
619
        $this->borderTopWidth = $topWidth;
620
        $this->borderRightWidth = $rightWidth;
621
        $this->borderBottomWidth = $bottomWidth;
622
        $this->borderLeftWidth = $leftWidth;
623
624
        if (is_string($colour)) {
625
            $this->setBorderColour($colour);
626
        } elseif ($colour !== null) {
627
            throw new \InvalidArgumentException('Invalid colour');
628
        }
629
630
        $this->calculateContentWidth();
631
        $this->generateBorderRows();
632
        $this->generatePaddingTopBottomRows();
633
634
        return $this;
635
    }
636
637
    public function setBorderTopWidth(int $width) : self
638
    {
639
        $this->borderTopWidth = $width;
640
641
        $this->generateBorderRows();
642
643
        return $this;
644
    }
645
646
    public function setBorderRightWidth(int $width) : self
647
    {
648
        $this->borderRightWidth = $width;
649
        $this->calculateContentWidth();
650
651
        $this->generatePaddingTopBottomRows();
652
653
        return $this;
654
    }
655
656
    public function setBorderBottomWidth(int $width) : self
657
    {
658
        $this->borderBottomWidth = $width;
659
660
        $this->generateBorderRows();
661
662
        return $this;
663
    }
664
665
    public function setBorderLeftWidth(int $width) : self
666
    {
667
        $this->borderLeftWidth = $width;
668
        $this->calculateContentWidth();
669
670
        $this->generatePaddingTopBottomRows();
671
672
        return $this;
673
    }
674
675
    public function setBorderColour(string $colour, $fallback = null) : self
676
    {
677
        $this->borderColour = ColourUtil::validateColour(
678
            $this->terminal,
679
            $colour,
680
            $fallback
681
        );
682
683
        $this->generateBorderRows();
684
        $this->generatePaddingTopBottomRows();
685
686
        return $this;
687
    }
688
689
    public function getBorderTopWidth() : int
690
    {
691
        return $this->borderTopWidth;
692
    }
693
694
    public function getBorderRightWidth() : int
695
    {
696
        return $this->borderRightWidth;
697
    }
698
699
    public function getBorderBottomWidth() : int
700
    {
701
        return $this->borderBottomWidth;
702
    }
703
704
    public function getBorderLeftWidth() : int
705
    {
706
        return $this->borderLeftWidth;
707
    }
708
709
    public function getBorderColour() : string
710
    {
711
        return $this->borderColour;
712
    }
713
714
    public function getBorderColourCode() : string
715
    {
716
        if (!ctype_digit($this->borderColour)) {
717
            $borderColourCode = self::$availableBackgroundColors[$this->borderColour];
718
        } else {
719
            $borderColourCode = sprintf("48;5;%s", $this->borderColour);
720
        }
721
722
        return sprintf("\033[%sm", $borderColourCode);
723
    }
724
}
725