Completed
Push — master ( db978a...536211 )
by Aydin
31s queued 11s
created

Locator::hasStyleForMenuItem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
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 hasStyleForMenuItem(MenuItemInterface $item) : bool
91
    {
92
        return isset($this->itemStyleMap[get_class($item)]);
93
    }
94
95
    public function getStyleForMenuItem(MenuItemInterface $item) : ItemStyle
96
    {
97
        if (!isset($this->itemStyleMap[get_class($item)])) {
98
            throw InvalidStyle::unregisteredItem(get_class($item));
99
        }
100
101
        $styleClass = $this->itemStyleMap[get_class($item)];
102
103
        return $this->getStyle($styleClass);
104
    }
105
106
    public function registerItemStyle(string $itemClass, ItemStyle $itemStyle) : void
107
    {
108
        if (isset($this->itemStyleMap[$itemClass])) {
109
            throw InvalidStyle::itemAlreadyRegistered($itemClass);
110
        }
111
112
        $this->itemStyleMap[$itemClass] = get_class($itemStyle);
113
        $this->styles[get_class($itemStyle)] = $itemStyle;
114
    }
115
}
116