Test Failed
Push — master ( 3eb0e4...9196b6 )
by Ivan
02:13
created

NavigationItemFactory::addMatchObjects()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 2
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Everlution\Navigation\Factory;
6
7
use Everlution\Navigation\Factory\Build\ItemConfig;
8
use Everlution\Navigation\Item;
9
use Everlution\Navigation\MatchableItem;
10
use Everlution\Navigation\NavigationItem;
11
use Everlution\Navigation\Factory\Build\UnsupportedItemClassException;
12
use Everlution\Navigation\RootNavigationItem;
13
use Everlution\Navigation\Factory\Build\Hydrator\Item as HydratorItem;
14
use Everlution\Navigation\Voter\Match;
15
16
/**
17
 * Class NavigationItemFactory.
18
 * @author Ivan Barlog <[email protected]>
19
 */
20
abstract class NavigationItemFactory extends HydratorContainer implements ItemFactory
21
{
22
    const OPTIONS_ITEMS = 'items';
23
24
    /** @var PropertyFactory */
25
    private $factory;
26
27
    public function __construct(PropertyFactory $factory)
28
    {
29
        $this->factory = $factory;
30
    }
31
32
    public function addHydrator(ItemConfig $config)
33
    {
34
        return $this->add($config);
35
    }
36
37
    /**
38
     * @param RootNavigationItem $navigation
39
     */
40
    public function build(RootNavigationItem &$navigation)
41
    {
42
        $data = $this->getData($navigation);
43
        foreach ($data[self::OPTIONS_ITEMS] as $item) {
44
            $item = $this->create($item);
45
            $navigation->addChild($item);
46
        }
47
    }
48
49
    /**
50
     * @param array $item
51
     * @return Item
52
     */
53
    public function create(array $item): Item
54
    {
55
        $instance = null;
56
        /** @var ItemConfig $hydrator */
57
        foreach ($this->getHydrators() as $hydrator) {
58
            try {
59
                $instance = $hydrator->toObject($item, $this);
60
                $this->addMatchObjects($instance, $item);
61
            } catch (UnsupportedItemClassException $exception) {
62
                continue;
63
            }
64
        }
65
66
        return $instance;
67
    }
68
69
    /**
70
     * @param NavigationItem $child
71
     * @return array
72
     */
73
    public function flatten(NavigationItem $child): array
74
    {
75
        $items = [];
76
        /** @var ItemConfig $hydrator */
77
        foreach ($this->getHydrators() as $hydrator) {
78
            try {
79
                $item = $hydrator->toArray($child, $this);
80
                $this->addMatchesConfig($item, $child);
81
82
                $items[] = $item;
83
            } catch (UnsupportedItemClassException $exception) {
84
                continue;
85
            }
86
        }
87
88
        return $items;
89
    }
90
91
    /**
92
     * @return PropertyFactory
93
     */
94
    protected function getFactory(): PropertyFactory
95
    {
96
        return $this->factory;
97
    }
98
99
    /**
100
     * @param RootNavigationItem $navigation
101
     * @return array
102
     */
103
    abstract protected function getData(RootNavigationItem &$navigation): array;
104
105
    /**
106
     * @param Item $item
107
     * @param array $config
108
     *
109
     * @return void
110
     */
111
    private function addMatchObjects(Item &$item, array $config)
112
    {
113
        if (!$item instanceof MatchableItem) {
114
            return;
115
        }
116
117
        foreach ($config[HydratorItem::OPTION_MATCHES] as $value) {
118
            /** @var Match $match */
119
            $match = $this->getFactory()->createProperty($value);
120
            $item->addMatch($match);
121
        }
122
    }
123
124
    /**
125
     * @param array $config
126
     * @param NavigationItem $item
127
     *
128
     * @return void
129
     */
130
    private function addMatchesConfig(array &$config, NavigationItem $item)
131
    {
132
        if (!$item instanceof MatchableItem) {
133
            return;
134
        }
135
136
        foreach ($item->getMatches() as $match) {
137
            $config[HydratorItem::OPTION_MATCHES][] = $this->getFactory()->flattenProperty($match);
138
        }
139
    }
140
}
141