Completed
Push — master ( a82150...06534f )
by Aydin
11s
created

MenuStyle   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 391
Duplicated Lines 10.23 %

Coupling/Cohesion

Components 4
Dependencies 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 37
lcom 4
cbo 1
dl 40
loc 391
rs 8.6
c 1
b 0
f 0

33 Methods

Rating   Name   Duplication   Size   Complexity  
A getDefaultStyleValues() 0 4 1
A __construct() 0 15 2
A getAvailableColours() 0 4 1
A getDisabledItemText() 0 9 1
A getSelectedSetCode() 10 10 1
A getSelectedUnsetCode() 10 10 1
A getUnselectedSetCode() 10 10 1
A getUnselectedUnsetCode() 10 10 1
A calculateContentWidth() 0 4 1
A getFg() 0 4 1
A setFg() 0 6 1
A getBg() 0 4 1
A setBg() 0 6 1
A getWidth() 0 4 1
A setWidth() 0 14 3
A getPadding() 0 4 1
A setPadding() 0 8 1
A getMargin() 0 4 1
A setMarginAuto() 0 7 1
A setMargin() 0 7 1
A getContentWidth() 0 4 1
A getRightHandPadding() 0 4 1
A getSelectedMarker() 0 4 1
A setSelectedMarker() 0 6 1
A getUnselectedMarker() 0 4 1
A setUnselectedMarker() 0 6 1
A getMarker() 0 4 2
A setItemExtra() 0 6 1
A getItemExtra() 0 4 1
A getDisplaysExtra() 0 4 1
A setDisplaysExtra() 0 6 1
A getTitleSeparator() 0 4 1
A setTitleSeparator() 0 6 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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 bool
78
     */
79
    private $marginAuto = false;
80
81
    /**
82
     * Default Values
83
     *
84
     * @var array
85
     */
86
    private static $defaultStyleValues = [
87
        'fg' => 'white',
88
        'bg' => 'blue',
89
        'width' => 100,
90
        'padding' => 2,
91
        'margin' => 2,
92
        'selectedMarker' => '●',
93
        'unselectedMarker' => '○',
94
        'itemExtra' => '✔',
95
        'displaysExtra' => false,
96
        'titleSeparator' => '=',
97
        'marginAuto' => false,
98
    ];
99
100
    public static function getDefaultStyleValues() : array
101
    {
102
        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...
103
    }
104
105
    /**
106
     * @var array
107
     */
108
    private static $availableForegroundColors = array(
109
        'black'   => array('set' => 30, 'unset' => 39),
110
        'red'     => array('set' => 31, 'unset' => 39),
111
        'green'   => array('set' => 32, 'unset' => 39),
112
        'yellow'  => array('set' => 33, 'unset' => 39),
113
        'blue'    => array('set' => 34, 'unset' => 39),
114
        'magenta' => array('set' => 35, 'unset' => 39),
115
        'cyan'    => array('set' => 36, 'unset' => 39),
116
        'white'   => array('set' => 37, 'unset' => 39),
117
        'default' => array('set' => 39, 'unset' => 39),
118
    );
119
120
    /**
121
     * @var array
122
     */
123
    private static $availableBackgroundColors = array(
124
        'black'   => array('set' => 40, 'unset' => 49),
125
        'red'     => array('set' => 41, 'unset' => 49),
126
        'green'   => array('set' => 42, 'unset' => 49),
127
        'yellow'  => array('set' => 43, 'unset' => 49),
128
        'blue'    => array('set' => 44, 'unset' => 49),
129
        'magenta' => array('set' => 45, 'unset' => 49),
130
        'cyan'    => array('set' => 46, 'unset' => 49),
131
        'white'   => array('set' => 47, 'unset' => 49),
132
        'default' => array('set' => 49, 'unset' => 49),
133
    );
134
135
    /**
136
     * @var array
137
     */
138
    private static $availableOptions = array(
139
        'bold'       => array('set' => 1, 'unset' => 22),
140
        'dim'        => array('set' => 2, 'unset' => 22),
141
        'underscore' => array('set' => 4, 'unset' => 24),
142
        'blink'      => array('set' => 5, 'unset' => 25),
143
        'reverse'    => array('set' => 7, 'unset' => 27),
144
        'conceal'    => array('set' => 8, 'unset' => 28)
145
    );
146
147
    /**
148
     * Initialise style
149
     */
150
    public function __construct(Terminal $terminal = null)
151
    {
152
        $this->terminal = $terminal ?: TerminalFactory::fromSystem();
153
154
        $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...
155
        $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...
156
        $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...
157
        $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...
158
        $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...
159
        $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...
160
        $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...
161
        $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...
162
        $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...
163
        $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...
164
    }
165
166
    public static function getAvailableColours() : array
167
    {
168
        return array_keys(self::$availableBackgroundColors);
169
    }
170
171
    public function getDisabledItemText(string $text) : string
172
    {
173
        return sprintf(
174
            "\033[%sm%s\033[%sm",
175
            self::$availableOptions['dim']['set'],
176
            $text,
177
            self::$availableOptions['dim']['unset']
178
        );
179
    }
180
    
181
    /**
182
     * Get the colour code set for Bg and Fg
183
     */
184 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...
185
    {
186
        return sprintf(
187
            "\033[%sm",
188
            implode(';', [
189
                self::$availableBackgroundColors[$this->getFg()]['set'],
190
                self::$availableForegroundColors[$this->getBg()]['set'],
191
            ])
192
        );
193
    }
194
195
    /**
196
     * Get the colour unset code for Bg and Fg
197
     */
198 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...
199
    {
200
        return sprintf(
201
            "\033[%sm",
202
            implode(';', [
203
                self::$availableBackgroundColors[$this->getBg()]['unset'],
204
                self::$availableForegroundColors[$this->getFg()]['unset'],
205
            ])
206
        );
207
    }
208
209
    /**
210
     * Get the inverted colour code
211
     */
212 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...
213
    {
214
        return sprintf(
215
            "\033[%sm",
216
            implode(';', [
217
                self::$availableBackgroundColors[$this->getBg()]['set'],
218
                self::$availableForegroundColors[$this->getFg()]['set'],
219
            ])
220
        );
221
    }
222
223
    /**
224
     * Get the inverted colour unset code
225
     */
226 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...
227
    {
228
        return sprintf(
229
            "\033[%sm",
230
            implode(';', [
231
                self::$availableBackgroundColors[$this->getBg()]['unset'],
232
                self::$availableForegroundColors[$this->getFg()]['unset'],
233
            ])
234
        );
235
    }
236
237
    /**
238
     * Calculate the contents width
239
     */
240
    protected function calculateContentWidth() : void
241
    {
242
        $this->contentWidth = $this->width - ($this->padding * 2);
243
    }
244
245
    public function getFg() : string
246
    {
247
        return $this->fg;
248
    }
249
250
    public function setFg(string $fg) : self
251
    {
252
        $this->fg = $fg;
253
254
        return $this;
255
    }
256
257
    public function getBg() : string
258
    {
259
        return $this->bg;
260
    }
261
262
    public function setBg(string $bg) : self
263
    {
264
        $this->bg = $bg;
265
266
        return $this;
267
    }
268
269
    public function getWidth() : int
270
    {
271
        return $this->width;
272
    }
273
274
    public function setWidth(int $width) : self
275
    {
276
        if ($width >= $this->terminal->getWidth()) {
277
            $width = $this->terminal->getWidth();
278
        }
279
280
        $this->width = $width;
281
        if ($this->marginAuto) {
282
            $this->setMarginAuto();
283
        }
284
        $this->calculateContentWidth();
285
286
        return $this;
287
    }
288
289
    public function getPadding() : int
290
    {
291
        return $this->padding;
292
    }
293
294
    public function setPadding(int $padding) : self
295
    {
296
        $this->padding = $padding;
297
298
        $this->calculateContentWidth();
299
300
        return $this;
301
    }
302
303
    public function getMargin() : int
304
    {
305
        return $this->margin;
306
    }
307
308
    public function setMarginAuto() : self
309
    {
310
        $this->marginAuto = true;
311
        $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...
312
        
313
        return $this;
314
    }
315
316
    public function setMargin(int $margin) : self
317
    {
318
        $this->marginAuto = false;
319
        $this->margin = $margin;
320
321
        return $this;
322
    }
323
324
    public function getContentWidth() : int
325
    {
326
        return $this->contentWidth;
327
    }
328
329
    /**
330
     * Get padding for right had side of content
331
     */
332
    public function getRightHandPadding(int $contentLength) : int
333
    {
334
        return $this->getContentWidth() - $contentLength + $this->getPadding();
335
    }
336
337
    public function getSelectedMarker() : string
338
    {
339
        return $this->selectedMarker;
340
    }
341
342
    public function setSelectedMarker(string $marker) : self
343
    {
344
        $this->selectedMarker = mb_substr($marker, 0, 1);
345
346
        return $this;
347
    }
348
349
    public function getUnselectedMarker() : string
350
    {
351
        return $this->unselectedMarker;
352
    }
353
354
    public function setUnselectedMarker(string $marker) : self
355
    {
356
        $this->unselectedMarker = mb_substr($marker, 0, 1);
357
358
        return $this;
359
    }
360
361
    /**
362
     * Get the correct marker for the item
363
     */
364
    public function getMarker(bool $selected) : string
365
    {
366
        return $selected ? $this->selectedMarker : $this->unselectedMarker;
367
    }
368
369
    public function setItemExtra(string $itemExtra) : self
370
    {
371
        $this->itemExtra = $itemExtra;
372
373
        return $this;
374
    }
375
376
    public function getItemExtra() : string
377
    {
378
        return $this->itemExtra;
379
    }
380
381
    public function getDisplaysExtra() : bool
382
    {
383
        return $this->displaysExtra;
384
    }
385
386
    public function setDisplaysExtra(bool $displaysExtra) : self
387
    {
388
        $this->displaysExtra = $displaysExtra;
389
390
        return $this;
391
    }
392
393
    public function getTitleSeparator() : string
394
    {
395
        return $this->titleSeparator;
396
    }
397
398
    public function setTitleSeparator(string $actionSeparator) : self
399
    {
400
        $this->titleSeparator = $actionSeparator;
401
402
        return $this;
403
    }
404
}
405