Completed
Pull Request — master (#39)
by Michael
02:49 queued 44s
created

MenuStyle   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 467
Duplicated Lines 8.57 %

Coupling/Cohesion

Components 3
Dependencies 3

Importance

Changes 0
Metric Value
wmc 36
lcom 3
cbo 3
dl 40
loc 467
rs 8.8
c 0
b 0
f 0

30 Methods

Rating   Name   Duplication   Size   Complexity  
A getAvailableColours() 0 4 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 13 2
A getPadding() 0 4 1
A setPadding() 0 8 1
A getMargin() 0 4 1
A setMargin() 0 8 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
B __construct() 0 34 5
A setItemExtra() 0 4 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\CliMenu\Terminal\TerminalInterface;
8
9
//TODO: B/W fallback
10
11
/**
12
 * Class MenuStyle
13
 *
14
 * @package PhpSchool\CliMenu
15
 * @author Michael Woodward <[email protected]>
16
 */
17
class MenuStyle
18
{
19
    /**
20
     * @var TerminalInterface
21
     */
22
    protected $terminal;
23
24
    /**
25
     * @var string
26
     */
27
    protected $fg;
28
29
    /**
30
     * @var string
31
     */
32
    protected $bg;
33
34
    /**
35
     * @var int
36
     */
37
    protected $width;
38
39
    /**
40
     * @var int
41
     */
42
    protected $padding;
43
44
    /**
45
     * @var int
46
     */
47
    protected $margin;
48
49
    /**
50
     * @var int
51
     */
52
    protected $contentWidth;
53
54
    /**
55
     * @var string
56
     */
57
    private $selectedMarker;
58
59
    /**
60
     * @var string
61
     */
62
    private $unselectedMarker;
63
64
    /**
65
     * @var string
66
     */
67
    private $itemExtra;
68
69
    /**
70
     * @var bool
71
     */
72
    private $displaysExtra;
73
74
    /**
75
     * @var string
76
     */
77
    private $titleSeparator;
78
79
    /**
80
     * @var string
81
     */
82
    private $allowedConsumer = 'PhpSchool\CliMenu\CliMenuBuilder';
83
84
    /**
85
     * @var array
86
     */
87
    private static $availableForegroundColors = array(
88
        'black'   => array('set' => 30, 'unset' => 39),
89
        'red'     => array('set' => 31, 'unset' => 39),
90
        'green'   => array('set' => 32, 'unset' => 39),
91
        'yellow'  => array('set' => 33, 'unset' => 39),
92
        'blue'    => array('set' => 34, 'unset' => 39),
93
        'magenta' => array('set' => 35, 'unset' => 39),
94
        'cyan'    => array('set' => 36, 'unset' => 39),
95
        'white'   => array('set' => 37, 'unset' => 39),
96
        'default' => array('set' => 39, 'unset' => 39),
97
    );
98
99
    /**
100
     * @var array
101
     */
102
    private static $availableBackgroundColors = array(
103
        'black'   => array('set' => 40, 'unset' => 49),
104
        'red'     => array('set' => 41, 'unset' => 49),
105
        'green'   => array('set' => 42, 'unset' => 49),
106
        'yellow'  => array('set' => 43, 'unset' => 49),
107
        'blue'    => array('set' => 44, 'unset' => 49),
108
        'magenta' => array('set' => 45, 'unset' => 49),
109
        'cyan'    => array('set' => 46, 'unset' => 49),
110
        'white'   => array('set' => 47, 'unset' => 49),
111
        'default' => array('set' => 49, 'unset' => 49),
112
    );
113
114
    /**
115
     * @var array
116
     */
117
    private static $availableOptions = array(
0 ignored issues
show
Unused Code introduced by
The property $availableOptions is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
118
        'bold'       => array('set' => 1, 'unset' => 22),
119
        'underscore' => array('set' => 4, 'unset' => 24),
120
        'blink'      => array('set' => 5, 'unset' => 25),
121
        'reverse'    => array('set' => 7, 'unset' => 27),
122
        'conceal'    => array('set' => 8, 'unset' => 28),
123
    );
124
125
    /**
126
     * Initialise style
127
     *
128
     * @param string $bg
129
     * @param string $fg
130
     * @param int $width
131
     * @param int $padding
132
     * @param int $margin
133
     * @param string $unselectedMarker
134
     * @param string $selectedMarker
135
     * @param string $itemExtra
136
     * @param bool $displaysExtra
137
     * @param string $titleSeparator
138
     * @param TerminalInterface $terminal
139
     * @throws InvalidInstantiationException
140
     */
141
    public function __construct(
142
        $bg = 'blue',
143
        $fg = 'white',
144
        $width = 100,
145
        $padding = 2,
146
        $margin = 2,
147
        $unselectedMarker = '○',
148
        $selectedMarker = '●',
149
        $itemExtra = '✔',
150
        $displaysExtra = false,
151
        $titleSeparator = '=',
152
        TerminalInterface $terminal = null
153
    ) {
154
        $builder = debug_backtrace();
155
        if (count($builder) < 2 || !isset($builder[1]['class']) || $builder[1]['class'] !== $this->allowedConsumer) {
156
            throw new InvalidInstantiationException(
157
                sprintf('The MenuStyle must be instantiated by "%s"', $this->allowedConsumer)
158
            );
159
        }
160
161
        $this->terminal        = $terminal ?: TerminalFactory::fromSystem();
162
        $this->bg              = $bg;
163
        $this->fg              = $fg;
164
        $this->padding         = $padding;
165
        $this->margin          = $margin;
166
        $this->itemExtra       = $itemExtra;
167
        $this->displaysExtra   = $displaysExtra;
168
        $this->titleSeparator  = $titleSeparator;
169
170
        $this->setUnselectedMarker($unselectedMarker);
171
        $this->setSelectedMarker($selectedMarker);
172
        $this->setWidth($width);
173
        $this->calculateContentWidth();
174
    }
175
176
    /**
177
     * @return array
178
     */
179
    public static function getAvailableColours()
180
    {
181
        return array_keys(self::$availableBackgroundColors);
182
    }
183
    
184
    /**
185
     * Get the colour code set for Bg and Fg
186
     *
187
     * @return string
188
     */
189 View Code Duplication
    public function getSelectedSetCode()
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...
190
    {
191
        return sprintf(
192
            "\033[%sm",
193
            implode(';', [
194
                self::$availableBackgroundColors[$this->getFg()]['set'],
195
                self::$availableForegroundColors[$this->getBg()]['set'],
196
            ])
197
        );
198
    }
199
200
    /**
201
     * Get the colour unset code for Bg and Fg
202
     *
203
     * @return string
204
     */
205 View Code Duplication
    public function getSelectedUnsetCode()
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...
206
    {
207
        return sprintf(
208
            "\033[%sm",
209
            implode(';', [
210
                self::$availableBackgroundColors[$this->getBg()]['unset'],
211
                self::$availableForegroundColors[$this->getFg()]['unset'],
212
            ])
213
        );
214
    }
215
216
    /**
217
     * Get the inverted colour code
218
     *
219
     * @return string
220
     */
221 View Code Duplication
    public function getUnselectedSetCode()
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...
222
    {
223
        return sprintf(
224
            "\033[%sm",
225
            implode(';', [
226
                self::$availableBackgroundColors[$this->getBg()]['set'],
227
                self::$availableForegroundColors[$this->getFg()]['set'],
228
            ])
229
        );
230
    }
231
232
    /**
233
     * Get the inverted colour unset code
234
     *
235
     * @return string
236
     */
237 View Code Duplication
    public function getUnselectedUnsetCode()
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...
238
    {
239
        return sprintf(
240
            "\033[%sm",
241
            implode(';', [
242
                self::$availableBackgroundColors[$this->getBg()]['unset'],
243
                self::$availableForegroundColors[$this->getFg()]['unset'],
244
            ])
245
        );
246
    }
247
248
    /**
249
     * Calculate the contents width
250
     */
251
    protected function calculateContentWidth()
252
    {
253
        $this->contentWidth = $this->width - ($this->padding*2) - ($this->margin*2);
254
    }
255
256
    /**
257
     * @return string
258
     */
259
    public function getFg()
260
    {
261
        return $this->fg;
262
    }
263
264
    /**
265
     * @param string $fg
266
     * @return MenuStyle
267
     */
268
    public function setFg($fg)
269
    {
270
        $this->fg = $fg;
271
272
        return $this;
273
    }
274
275
    /**
276
     * @return string
277
     */
278
    public function getBg()
279
    {
280
        return $this->bg;
281
    }
282
283
    /**
284
     * @param string $bg
285
     * @return MenuStyle
286
     */
287
    public function setBg($bg)
288
    {
289
        $this->bg = $bg;
290
291
        return $this;
292
    }
293
294
    /**
295
     * @return int
296
     */
297
    public function getWidth()
298
    {
299
        return $this->width;
300
    }
301
302
    /**
303
     * @param int $width
304
     * @return MenuStyle
305
     */
306
    public function setWidth($width)
307
    {
308
        $availableWidth = $this->terminal->getWidth() - ($this->margin * 2) - ($this->padding * 2);
309
310
        if ($width >= $availableWidth) {
311
            $width = $availableWidth;
312
        }
313
314
        $this->width = $width;
315
        $this->calculateContentWidth();
316
317
        return $this;
318
    }
319
320
    /**
321
     * @return int
322
     */
323
    public function getPadding()
324
    {
325
        return $this->padding;
326
    }
327
328
    /**
329
     * @param int $padding
330
     * @return MenuStyle
331
     */
332
    public function setPadding($padding)
333
    {
334
        $this->padding = $padding;
335
336
        $this->calculateContentWidth();
337
338
        return $this;
339
    }
340
341
    /**
342
     * @return int
343
     */
344
    public function getMargin()
345
    {
346
        return $this->margin;
347
    }
348
349
    /**
350
     * @param int $margin
351
     * @return MenuStyle
352
     */
353
    public function setMargin($margin)
354
    {
355
        $this->margin = $margin;
356
357
        $this->calculateContentWidth();
358
359
        return $this;
360
    }
361
362
    /**
363
     * @return int
364
     */
365
    public function getContentWidth()
366
    {
367
        return $this->contentWidth;
368
    }
369
370
    /**
371
     * Get padding for right had side of content
372
     *
373
     * @param $contentLength
374
     * @return int
375
     */
376
    public function getRightHandPadding($contentLength)
377
    {
378
        return $this->getContentWidth() - $contentLength + $this->getPadding();
379
    }
380
381
    /**
382
     * @return string
383
     */
384
    public function getSelectedMarker()
385
    {
386
        return $this->selectedMarker;
387
    }
388
389
    /**
390
     * @param string $marker
391
     * @return $this
392
     */
393
    public function setSelectedMarker($marker)
394
    {
395
        $this->selectedMarker = mb_substr($marker, 0, 1);
396
397
        return $this;
398
    }
399
400
    /**
401
     * @return string
402
     */
403
    public function getUnselectedMarker()
404
    {
405
        return $this->unselectedMarker;
406
    }
407
408
    /**
409
     * @param string $marker
410
     * @return $this
411
     */
412
    public function setUnselectedMarker($marker)
413
    {
414
        $this->unselectedMarker = mb_substr($marker, 0, 1);
415
416
        return $this;
417
    }
418
419
    /**
420
     * Get the correct marker for the item
421
     *
422
     * @param bool $selected
423
     * @return string
424
     */
425
    public function getMarker($selected)
426
    {
427
        return $selected ? $this->selectedMarker : $this->unselectedMarker;
428
    }
429
430
    /**
431
     * @param string $itemExtra
432
     */
433
    public function setItemExtra($itemExtra)
434
    {
435
        $this->itemExtra = $itemExtra;
436
    }
437
438
    /**
439
     * @return string
440
     */
441
    public function getItemExtra()
442
    {
443
        return $this->itemExtra;
444
    }
445
446
    /**
447
     * @return bool
448
     */
449
    public function getDisplaysExtra()
450
    {
451
        return $this->displaysExtra;
452
    }
453
454
    /**
455
     * @param bool $displaysExtra
456
     * @return $this
457
     */
458
    public function setDisplaysExtra($displaysExtra)
459
    {
460
        $this->displaysExtra = $displaysExtra;
461
462
        return $this;
463
    }
464
465
    /**
466
     * @return string
467
     */
468
    public function getTitleSeparator()
469
    {
470
        return $this->titleSeparator;
471
    }
472
473
    /**
474
     * @param string $actionSeparator
475
     * @return $this
476
     */
477
    public function setTitleSeparator($actionSeparator)
478
    {
479
        $this->titleSeparator = $actionSeparator;
480
481
        return $this;
482
    }
483
}
484