Completed
Pull Request — master (#301)
by personal
02:13
created

Graph::getRootNodes()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 10
c 0
b 0
f 0
nc 7
nop 0
dl 0
loc 21
rs 8.7624
1
<?php
2
3
/*
4
 * (c) Jean-François Lépine <https://twitter.com/Halleck45>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Hal\Component\Tree;
11
12
class Graph implements \Countable
13
{
14
    /**
15
     * @var array
16
     */
17
    private $datas = array();
18
19
    /**
20
     * @var Edge[]
21
     */
22
    private $edges = array();
23
24
    /**
25
     * @param Node $node
26
     * @return $this
27
     */
28
    public function insert(Node $node)
29
    {
30
        if ($this->has($node->getKey())) {
31
            throw new GraphException(sprintf('node %s is already present', $node->getKey()));
32
        }
33
        $this->datas[$node->getKey()] = $node;
34
        return $this;
35
    }
36
37
    /**
38
     * @param Node $from
39
     * @param Node $to
40
     * @return $this
41
     */
42
    public function addEdge(Node $from, Node $to)
43
    {
44
        if (!$this->has($from->getKey())) {
45
            throw new GraphException('from is not is in the graph');
46
        }
47
        if (!$this->has($to->getKey())) {
48
            throw new GraphException('to is not is in the graph');
49
        }
50
51
        $edge = new Edge($from, $to);
52
        $from->addEdge($edge);
53
        $to->addEdge($edge);
54
        array_push($this->edges, $edge);
55
56
        return $this;
57
    }
58
59
    /**
60
     * @return string
61
     */
62
    public function asString()
63
    {
64
        $string = '';
65
        foreach ($this->all() as $node) {
66
            $string .= sprintf("%s;\n", $node->getKey());
67
        }
68
        foreach ($this->getEdges() as $edge) {
69
            $string .= sprintf("%s;\n", $edge->asString());
70
        }
71
        return $string;
72
    }
73
74
    /**
75
     * @return Edge[]
76
     */
77
    public function getEdges()
78
    {
79
        return $this->edges;
80
    }
81
82
    /**
83
     * @param $key
84
     * @return null
85
     */
86
    public function get($key)
87
    {
88
        return $this->has($key) ? $this->datas[$key] : null;
89
    }
90
91
    /**
92
     * @param $key
93
     * @return bool
94
     */
95
    public function has($key)
96
    {
97
        return isset($this->datas[$key]);
98
    }
99
100
    /**
101
     * @return int
102
     */
103
    public function count()
104
    {
105
        return sizeof($this->datas);
106
    }
107
108
    /**
109
     * @return Node[]
110
     */
111
    public function all()
112
    {
113
        return $this->datas;
114
    }
115
116
    /**
117
     * @return $this
118
     */
119
    public function resetVisits()
120
    {
121
        foreach ($this->all() as $node) {
122
            $node->visited = false;
123
        }
124
        return $this;
125
    }
126
127
    /**
128
     * Get the list of all root nodes
129
     *
130
     *      we can have array of roots : graph can be a "forest"
131
     *
132
     * @return array
133
     */
134
    public function getRootNodes()
135
    {
136
        $roots = [];
137
        foreach ($this->all() as $node) {
138
139
            $isRoot = true;
140
141
            foreach ($node->getEdges() as $edge) {
142
                if ($edge->getTo() == $node) {
143
                    $isRoot = false;
144
                }
145
            }
146
147
148
            if ($isRoot) {
149
                array_push($roots, $node);
150
            }
151
        }
152
153
        return $roots;
154
    }
155
}
156