Tree::initItems()   B
last analyzed

Complexity

Conditions 6
Paths 11

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 8.5906
c 0
b 0
f 0
cc 6
eloc 15
nc 11
nop 1
1
<?php
2
3
namespace WebComplete\core\utils\tree;
4
5
use WebComplete\core\entity\AbstractEntity;
6
7
class Tree
8
{
9
    /**
10
     * @var AbstractEntity[]
11
     */
12
    protected $items = [];
13
    protected $root = [];
14
    protected $parentIds = [];
15
    protected $childrenIds = [];
16
    protected $parentField;
17
    protected $sortField;
18
19
    /**
20
     * @param AbstractEntity[] $items
21
     * @param string $parentField
22
     * @param string $sortField
23
     *
24
     * @throws \InvalidArgumentException
25
     */
26
    public function __construct(array $items, string $parentField = 'parent_id', string $sortField = 'sort')
27
    {
28
        $this->parentField = $parentField;
29
        $this->sortField = $sortField;
30
        $this->initItems($items);
31
    }
32
33
    /**
34
     * @param $id
35
     *
36
     * @return null|AbstractEntity
37
     */
38
    public function getItem($id)
39
    {
40
        return $this->items[$id] ?? null;
41
    }
42
43
    /**
44
     * @return AbstractEntity[]
45
     */
46
    public function getAllItems(): array
47
    {
48
        return $this->items;
49
    }
50
51
    /**
52
     * @return AbstractEntity[]
53
     */
54
    public function getRootItems(): array
55
    {
56
        $result = [];
57
        foreach ($this->root as $id) {
58
            if ($item = $this->getItem($id)) {
59
                $result[$id] = $item;
60
            }
61
        }
62
        return $result;
63
    }
64
65
    /**
66
     * @param $id
67
     *
68
     * @return null|AbstractEntity
69
     */
70
    public function getParent($id)
71
    {
72
        return $this->getItem($this->parentIds[$id] ?? null);
73
    }
74
75
    /**
76
     * @param $id
77
     *
78
     * @return AbstractEntity[]
79
     */
80
    public function getChildren($id): array
81
    {
82
        $result = [];
83
        $childrenIds = (array)($this->childrenIds[$id] ?? []);
84
        foreach ($childrenIds as $childId) {
85
            if ($child = $this->getItem($childId)) {
86
                $result[$childId] = $child;
87
            }
88
        }
89
        return $result;
90
    }
91
92
    /**
93
     * @param array $items
94
     *
95
     * @throws \InvalidArgumentException
96
     */
97
    protected function initItems(array $items)
98
    {
99
        foreach ($items as $k => $item) {
100
            if (!$item instanceof AbstractEntity) {
101
                throw new \InvalidArgumentException('Item ' . $k . ' is not an instance of ' . AbstractEntity::class);
102
            }
103
            $this->items[$item->getId()] = $item;
104
        }
105
106
        \uasort($this->items, function (AbstractEntity $item1, AbstractEntity $item2) {
107
            return $item1->get($this->sortField) <=> $item2->get($this->sortField);
108
        });
109
110
        foreach ($this->items as $item) {
111
            $id = $item->getId();
112
            $parentId = $item->get($this->parentField);
113
            $this->parentIds[$id] = $parentId;
114
            isset($this->childrenIds[$parentId])
115
                ? $this->childrenIds[$parentId][] = $id
116
                : $this->childrenIds[$parentId] = [$id];
117
118
            if (!$parentId) {
119
                $this->root[] = $item->getId();
120
            }
121
        }
122
    }
123
}
124