Completed
Push — master ( aba289...58e266 )
by Ventaquil
02:10
created

Builder::addConnection()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
c 0
b 0
f 0
rs 9.3142
cc 3
eloc 11
nc 4
nop 1
1
<?php
2
3
namespace PHPAlgorithms\GraphTools\Graph;
4
5
use PHPAlgorithms\GraphTools\Abstracts\BuilderAbstract;
6
use PHPAlgorithms\GraphTools\Graph;
7
8
/**
9
 * Class Builder
10
 * @package PHPAlgorithms\GraphTools\Graph
11
 * @method  Connection[] getConnections()
12
 * @method Node[] getNodes()
13
 * @property-read Connection[] $connections
14
 * @property-read Node[] $nodes
15
 */
16
class Builder extends BuilderAbstract
17
{
18
    private const OPERATION_ADD_CONNECTION = 2;
19
20
    private const OPERATION_ADD_NODE = 1;
21
22
    private const OPERATION_NO_OPERATION = 0;
23
24
    /**
25
     * @var array $allowedGet
26
     */
27
    protected $allowedGet = array('connections', 'nodes');
28
29
    /**
30
     * @var Connection[] $connections
31
     */
32
    protected $connections = array();
33
34
    /**
35
     * @var Connection|null $lastConnection
36
     */
37
    private $lastConnection = null;
38
39
    /**
40
     * @var integer $lastOperation
41
     */
42
    private $lastOperation = self::OPERATION_NO_OPERATION;
43
44
    /**
45
     * @var Node[] $nodes
46
     */
47
    protected $nodes = array();
48
49
    /**
50
     * @param Connection $connection
51
     * @return Builder
52
     */
53
    public function addConnection(Connection $connection) : Builder
54
    {
55
        try {
56
            $this->addNode($connection->from);
57
        } catch (Builder\Exception $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
58
        }
59
60
61
        try {
62
            $this->addNode($connection->to);
63
        } catch (Builder\Exception $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
64
        }
65
66
        $this->connections[] = $connection;
67
68
        $this->lastOperation = self::OPERATION_ADD_CONNECTION;
69
70
        $this->lastConnection = $connection;
71
72
        return $this;
73
    }
74
75
    /**
76
     * @param Node $node
77
     * @return Builder
78
     * @throws Builder\Exception
79
     */
80
    public function addNode(Node $node) : Builder
81
    {
82
        if (in_array($node, $this->nodes, true)) {
83
            throw new Builder\Exception('Node was added before');
84
        }
85
86
        $this->nodes[] = $node;
87
88
        $this->lastOperation = self::OPERATION_ADD_NODE;
89
90
        return $this;
91
    }
92
93
    /**
94
     * @return Graph
95
     */
96
    public function build() : Graph
97
    {
98
        return new Graph($this->nodes, $this->connections);
99
    }
100
101
    /**
102
     * @param Node $from
103
     * @param Node $to
104
     * @param float|null $weight
105
     * @return Builder
106
     */
107
    public function connect(Node $from, Node $to, float $weight = null) : Builder
108
    {
109
        $this->addConnection(new Connection($from, $to, $weight));
110
111
        return $this;
112
    }
113
114
    /**
115
     * @return Node\Builder
116
     */
117
    public function createNode() : Node\Builder
118
    {
119
        return new Node\Builder($this);
120
    }
121
122
    /**
123
     * @return Connection\Builder
124
     */
125
    public function createConnection() : Connection\Builder
126
    {
127
        return new Connection\Builder($this);
128
    }
129
130
    /**
131
     * @param integer $index
132
     * @return Node
133
     */
134
    public function getNode(int $index) : Node
135
    {
136
        return $this->nodes[$index];
137
    }
138
139
    /**
140
     * @return Builder
141
     * @throws Builder\Exception
142
     */
143
    public function viceVersa() : Builder
144
    {
145
        if (($this->lastOperation !== self::OPERATION_ADD_CONNECTION) || is_null($this->lastConnection)) {
146
            throw new Builder\Exception('To which connection, hm?');
147
        }
148
149
        $lastConnection = $this->lastConnection;
150
151
        $this->addConnection(new Connection($lastConnection->to, $lastConnection->from, $lastConnection->weight));
152
153
        $this->lastOperation = self::OPERATION_NO_OPERATION;
154
155
        $this->lastConnection = null;
156
157
        return $this;
158
    }
159
}
160