Completed
Push — master ( 2edd9d...d97347 )
by Aydin
21s queued 11s
created

Locator   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 33
dl 0
loc 80
rs 10
c 2
b 0
f 0
wmc 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A getStyleForMenuItem() 0 9 2
A setStyle() 0 11 3
A getStyle() 0 7 2
A importFrom() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpSchool\CliMenu\Style;
6
7
use PhpSchool\CliMenu\MenuItem\AsciiArtItem;
8
use PhpSchool\CliMenu\MenuItem\CheckboxItem;
9
use PhpSchool\CliMenu\MenuItem\LineBreakItem;
10
use PhpSchool\CliMenu\MenuItem\MenuItemInterface;
11
use PhpSchool\CliMenu\MenuItem\MenuMenuItem;
12
use PhpSchool\CliMenu\MenuItem\RadioItem;
13
use PhpSchool\CliMenu\MenuItem\SelectableItem;
14
use PhpSchool\CliMenu\MenuItem\SplitItem;
15
use PhpSchool\CliMenu\MenuItem\StaticItem;
16
use PhpSchool\CliMenu\Style\Exception\InvalidStyle;
17
use function PhpSchool\CliMenu\Util\mapWithKeys;
18
19
class Locator
20
{
21
    /**
22
     * @var array
23
     */
24
    private $itemStyleMap = [
25
        StaticItem::class => DefaultStyle::class,
26
        AsciiArtItem::class => DefaultStyle::class,
27
        LineBreakItem::class => DefaultStyle::class,
28
        SplitItem::class => DefaultStyle::class,
29
        SelectableItem::class => SelectableStyle::class,
30
        MenuMenuItem::class => SelectableStyle::class,
31
        CheckboxItem::class => CheckboxStyle::class,
32
        RadioItem::class => RadioStyle::class,
33
    ];
34
35
    /**
36
     * @var array
37
     */
38
    private $styles;
39
40
    public function __construct()
41
    {
42
        $this->styles = [
43
            DefaultStyle::class => new DefaultStyle(),
44
            SelectableStyle::class => new SelectableStyle(),
45
            CheckboxStyle::class => new CheckboxStyle(),
46
            RadioStyle::class => new RadioStyle()
47
        ];
48
    }
49
50
    /**
51
     * For each of our unmodified item styles, we replace ours with the versions
52
     * from the given style locator.
53
     *
54
     * @param Locator $other
55
     */
56
    public function importFrom(self $other) : void
57
    {
58
        $this->styles = mapWithKeys(
59
            $this->styles,
60
            function ($styleClass, ItemStyle $instance) use ($other) {
61
                return $instance->hasChangedFromDefaults()
62
                    ? $instance
63
                    : $other->getStyle($styleClass);
64
            }
65
        );
66
    }
67
68
    public function getStyle(string $styleClass) : ItemStyle
69
    {
70
        if (!isset($this->styles[$styleClass])) {
71
            throw InvalidStyle::unregisteredStyle($styleClass);
72
        }
73
74
        return $this->styles[$styleClass];
75
    }
76
77
    public function setStyle(ItemStyle $itemStyle, string $styleClass) : void
78
    {
79
        if (!isset($this->styles[$styleClass])) {
80
            throw InvalidStyle::unregisteredStyle($styleClass);
81
        }
82
83
        if (!$itemStyle instanceof $styleClass) {
84
            throw InvalidStyle::notSubClassOf($styleClass);
85
        }
86
87
        $this->styles[$styleClass] = $itemStyle;
88
    }
89
90
    public function getStyleForMenuItem(MenuItemInterface $item) : ItemStyle
91
    {
92
        if (!isset($this->itemStyleMap[get_class($item)])) {
93
            throw InvalidStyle::unregisteredItem(get_class($item));
94
        }
95
96
        $styleClass = $this->itemStyleMap[get_class($item)];
97
98
        return $this->getStyle($styleClass);
99
    }
100
}
101