IndexNode   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 1
dl 0
loc 133
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A getIndexObject() 0 4 1
A setIndexObject() 0 8 1
A getChildren() 0 4 1
A getParent() 0 4 1
A getChild() 0 4 2
A hasChild() 0 4 1
A addChild() 0 12 3
A addChildren() 0 9 2
A getNodeByPath() 0 16 3
A recursiveCount() 0 8 1
A count() 0 4 1
1
<?php
2
3
namespace Storeman\Index;
4
5
/**
6
 * A node within the object index tree.
7
 */
8
class IndexNode implements \Countable
9
{
10
    /**
11
     * @var IndexObject
12
     */
13
    protected $indexObject;
14
15
    /**
16
     * @var IndexNode[]
17
     */
18
    protected $children = [];
19
20
    /**
21
     * @var IndexNode
22
     */
23
    protected $parent;
24
25
    /**
26
     * For the construction of a root node both arguments have to be null.
27
     * For the construction of regular or leaf nodes both arguments have to be given.
28
     *
29
     * @param IndexObject $indexObject
30
     * @param IndexNode $parent
31
     */
32
    public function __construct(IndexObject $indexObject = null, IndexNode $parent = null)
33
    {
34
        assert(($indexObject === null) === ($parent === null));
35
36
        $this->indexObject = $indexObject;
37
        $this->parent = $parent;
38
    }
39
40
    public function getIndexObject(): IndexObject
41
    {
42
        return $this->indexObject;
43
    }
44
45
    public function setIndexObject(IndexObject $indexObject): IndexNode
46
    {
47
        assert($this->indexObject->getRelativePath() === $indexObject->getRelativePath());
48
49
        $this->indexObject = $indexObject;
50
51
        return $this;
52
    }
53
54
    /**
55
     * Returns map from index object basename to child node.
56
     *
57
     * @return array
58
     */
59
    public function getChildren(): array
60
    {
61
        return $this->children;
62
    }
63
64
    public function getParent(): ?IndexNode
65
    {
66
        return $this->parent;
67
    }
68
69
    public function getChild(string $name): ?IndexNode
70
    {
71
        return array_key_exists($name, $this->children) ? $this->children[$name] : null;
72
    }
73
74
    public function hasChild(string $name): bool
75
    {
76
        return array_key_exists($name, $this->children);
77
    }
78
79
    public function addChild(IndexNode $indexNode): IndexNode
80
    {
81
        assert($this->indexObject === null || $this->indexObject->isDirectory());
82
        assert($this->indexObject === null || strpos($indexNode->getIndexObject()->getRelativePath(), $this->indexObject->getRelativePath()) === 0);
83
84
        $this->children[$indexNode->indexObject->getBasename()] = $indexNode;
85
86
        // ensure lexicographical order
87
        ksort($this->children);
88
89
        return $this;
90
    }
91
92
    public function addChildren(array $children): IndexNode
93
    {
94
        foreach ($children as $child)
95
        {
96
            $this->addChild($child);
97
        }
98
99
        return $this;
100
    }
101
102
    public function getNodeByPath(string $path): ?IndexNode
103
    {
104
        $current = $this;
105
106
        foreach (explode('/', $path) as $pathPart)
107
        {
108
            $current = $current->getChild($pathPart);
109
110
            if ($current === null)
111
            {
112
                break;
113
            }
114
        }
115
116
        return $current;
117
    }
118
119
    /**
120
     * Recursively counts all children and its children and returns total.
121
     *
122
     * @return int
123
     */
124
    public function recursiveCount()
125
    {
126
        return count($this) + array_reduce($this->children, function(int $carry, IndexNode $node) {
127
128
            return $carry + $node->recursiveCount();
129
130
        }, 0);
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    public function count()
137
    {
138
        return count($this->children);
139
    }
140
}
141