Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
87.88% covered (warning)
87.88%
29 / 33
92.31% covered (success)
92.31%
12 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
Node
87.88% covered (warning)
87.88%
29 / 33
92.31% covered (success)
92.31%
12 / 13
26.11
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getData
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setData
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isEqual
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 setNodeRelative
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 setEdge
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getEdge
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasNeighbor
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
20
 getEdgeByNeighbor
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
4
 getEdges
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 removeEdges
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNeighbors
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS\Stdlib\Graph
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace phpOMS\Stdlib\Graph;
16
17/**
18 * Node class.
19 *
20 * @package phpOMS\Stdlib\Graph
21 * @license OMS License 2.0
22 * @link    https://jingga.app
23 * @since   1.0.0
24 */
25class Node
26{
27    /**
28     * Node id.
29     *
30     * @var string
31     * @since 1.0.0
32     */
33    private string $id;
34
35    /**
36     * Node data.
37     *
38     * @var mixed
39     * @since 1.0.0
40     */
41    private $data = null;
42
43    /**
44     * Edges.
45     *
46     * @var Edge[]
47     * @since 1.0.0
48     */
49    protected array $edges = [];
50
51    /**
52     * Constructor.
53     *
54     * @param string $id   Node id
55     * @param mixed  $data Node data
56     *
57     * @since 1.0.0
58     */
59    public function __construct(string $id, mixed $data = null)
60    {
61        $this->id   = $id;
62        $this->data = $data;
63    }
64
65    /**
66     * Get node id.
67     *
68     * @return string
69     *
70     * @since 1.0.0
71     */
72    public function getId() : string
73    {
74        return $this->id;
75    }
76
77    /**
78     * Get data.
79     *
80     * @return mixed
81     *
82     * @since 1.0.0
83     */
84    public function getData() : mixed
85    {
86        return $this->data;
87    }
88
89    /**
90     * Set data.
91     *
92     * @param mixed $data Node data
93     *
94     * @return void
95     *
96     * @since 1.0.0
97     */
98    public function setData(mixed $data) : void
99    {
100        $this->data = $data;
101    }
102
103    /**
104     * Compare with other node.
105     *
106     * @param Node $node Node
107     *
108     * @return bool
109     *
110     * @since 1.0.0
111     */
112    public function isEqual(self $node) : bool
113    {
114        return $this->id === $node->getId() && $this->data === $node->getData();
115    }
116
117    /**
118     * Set a relative undirected node.
119     *
120     * @param Node $node       Graph node
121     * @param int  $key        Index for absolute position
122     * @param bool $isDirected Is directed
123     *
124     * @return Edge
125     *
126     * @since 1.0.0
127     */
128    public function setNodeRelative(self $node, int $key = null, bool $isDirected = false) : Edge
129    {
130        $edge = new Edge($this, $node, 0.0, $isDirected);
131        $this->setEdge($edge, $key);
132
133        if (!$edge->isDirected) {
134            $node->setEdge($edge);
135        }
136
137        return $edge;
138    }
139
140    /**
141     * Add edge to node.
142     *
143     * @param Edge $edge Graph edge
144     * @param int  $key  Index for absolute position
145     *
146     * @return Node
147     *
148     * @since 1.0.0
149     */
150    public function setEdge(Edge $edge, int $key = null) : self
151    {
152        if ($key === null) {
153            $this->edges[] = $edge;
154        } else {
155            $this->edges[$key] = $edge;
156        }
157
158        return $this;
159    }
160
161    /**
162     * Get graph edge.
163     *
164     * @param int $key Edge key
165     *
166     * @return null|Edge
167     *
168     * @since 1.0.0
169     */
170    public function getEdge(int $key) : ?Edge
171    {
172        return $this->edges[$key] ?? null;
173    }
174
175    /**
176     * Check if the node has a certain neighbor
177     *
178     * @param Node $node Neighbor node
179     *
180     * @return bool
181     *
182     * @since 1.0.0
183     */
184    public function hasNeighbor(self $node) : bool
185    {
186        foreach ($this->edges as $edge) {
187            if ($edge->node1->isEqual($node) || $edge->node2->isEqual($node)) {
188                return true;
189            }
190        }
191
192        return false;
193    }
194
195    /**
196     * Get graph edge by neighbor.
197     *
198     * @param Node $node Neighbor node
199     *
200     * @return null|Edge
201     *
202     * @since 1.0.0
203     */
204    public function getEdgeByNeighbor(self $node) : ?Edge
205    {
206        foreach ($this->edges as $edge) {
207            if ($edge->node1->isEqual($node) || $edge->node2->isEqual($node)) {
208                return $edge;
209            }
210        }
211
212        return null;
213    }
214
215    /**
216     * Get graph edges
217     *
218     * @return Edge[]
219     *
220     * @since 1.0.0
221     */
222    public function getEdges() : array
223    {
224        return $this->edges;
225    }
226
227    /**
228     * Removes all edges / neighbours from the node
229     *
230     * @return void
231     *
232     * @since 1.0.0
233     */
234    public function removeEdges() : void
235    {
236        $this->edges = [];
237    }
238
239    /**
240     * Get all node neighbors.
241     *
242     * @return Node[]
243     *
244     * @since 1.0.0
245     */
246    public function getNeighbors() : array
247    {
248        $neighbors = [];
249
250        foreach ($this->edges as $edge) {
251            $nodes = $edge->getNodes();
252
253            $neighbors[] = $nodes[0] !== null && !$this->isEqual($nodes[0])
254                ? $nodes[0]
255                : $nodes[1];
256        }
257
258        return $neighbors;
259    }
260}