Passed
Push — master ( e9839e...f54444 )
by Sergey
02:47
created

Zone::getNode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2
Metric Value
dl 0
loc 10
ccs 5
cts 5
cp 1
rs 9.4285
cc 2
eloc 5
nc 2
nop 1
crap 2
1
<?php
2
/**
3
 * @author: Viskov Sergey
4
 * @date  : 4/12/16
5
 * @time  : 1:00 PM
6
 */
7
8
namespace LTDBeget\dns\configurator;
9
10
use LTDBeget\dns\configurator\deserializer\ArrayDeserializer;
11
use LTDBeget\dns\configurator\deserializer\PlainDeserializer;
12
use LTDBeget\dns\configurator\errors\ErrorsStore;
13
use LTDBeget\dns\configurator\errors\ValidationError;
14
use LTDBeget\dns\configurator\traits\RecordsIterateTrait;
15
use LTDBeget\dns\configurator\validators\OriginValidator;
16
use LTDBeget\dns\configurator\validators\SoaNumberCheck;
17
use LTDBeget\dns\configurator\zoneEntities\Node;
18
use LTDBeget\dns\configurator\zoneEntities\record\AaaaRecord;
19
use LTDBeget\dns\configurator\zoneEntities\record\ARecord;
20
use LTDBeget\dns\configurator\zoneEntities\record\base\Record;
21
use LTDBeget\dns\configurator\zoneEntities\record\CnameRecord;
22
use LTDBeget\dns\configurator\zoneEntities\record\MxRecord;
23
use LTDBeget\dns\configurator\zoneEntities\record\NsRecord;
24
use LTDBeget\dns\configurator\zoneEntities\record\PtrRecord;
25
use LTDBeget\dns\configurator\zoneEntities\record\SoaRecord;
26
use LTDBeget\dns\configurator\zoneEntities\record\SrvRecord;
27
use LTDBeget\dns\configurator\zoneEntities\record\TxtRecord;
28
use LTDBeget\dns\enums\eErrorCode;
29
use LTDBeget\dns\enums\eRecordType;
30
31
/**
32
 * Class Zone
33
 *
34
 * @package LTDBeget\dns\configurator
35
 * @method ARecord[] iterateA()
36
 * @method AaaaRecord[] iterateAaaa()
37
 * @method CnameRecord[] iterateCname()
38
 * @method MxRecord[] iterateMx()
39
 * @method NsRecord[] iterateNs()
40
 * @method PtrRecord[] iteratePtr()
41
 * @method SoaRecord[] iterateSoa()
42
 * @method SrvRecord[] iterateSrv()
43
 * @method TxtRecord[] iterateTxt()
44
 */
45
class Zone
46
{
47
    use RecordsIterateTrait;
48
49
    /**
50
     * @var String
51
     */
52
    private $origin;
53
    /**
54
     * @var Node[] $nodes
55
     */
56
    private $nodes = [];
57
    /**
58
     * @var ErrorsStore
59
     */
60
    private $errorsStore;
61
62
    /**
63
     * @param $origin
64
     */
65 1
    public function __construct(string $origin)
66
    {
67 1
        $this->origin      = mb_strtolower(trim($origin));
68 1
        $this->errorsStore = new ErrorsStore();
69 1
    }
70
71
    /**
72
     * @param string $origin
73
     * @param string $plainData
74
     * @return Zone
75
     */
76 1
    public static function fromString(string $origin, string $plainData) : Zone
77
    {
78 1
        return PlainDeserializer::deserialize(new self($origin), $plainData);
79
    }
80
81
    /**
82
     * @param string $origin
83
     * @param array  $arrayData
84
     * @return Zone
85
     */
86
    public static function fromArray(string $origin, array $arrayData) : Zone
87
    {
88
        return ArrayDeserializer::deserialize(new self($origin), $arrayData);
89
    }
90
91
    /**
92
     * @return string
93
     */
94 1
    public function __toString() : string
95
    {
96 1
        $this->sort();
97 1
        $records = [];
98 1
        foreach ($this->iterateRecords() as $record) {
99 1
            $records[] = (string) $record;
100
        }
101
102 1
        return implode("\n", $records);
103
    }
104
105
    /**
106
     * Sort zone by node names and record types
107
     */
108 1
    public function sort()
109
    {
110 1
        $nodes = $this->nodes;
111
        /** @var Node[] $_nodes */
112 1
        $_nodes = [];
113 1
        foreach (['@', 'www', '*'] as $node_name) {
114 1
            if (isset($nodes[$node_name])) {
115 1
                $_nodes[$node_name] = $nodes[$node_name];
116 1
                unset($nodes[$node_name]);
117
            }
118
        }
119
120 1
        ksort($nodes);
121 1
        $this->nodes = array_merge($_nodes, $nodes);
1 ignored issue
show
Documentation Bug introduced by
It seems like array_merge($_nodes, $nodes) of type array is incompatible with the declared type array<integer,object<LTD...tor\zoneEntities\Node>> of property $nodes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
122
123 1
        foreach ($this->iterateNodes() as $node) {
124 1
            $node->sort();
125
        }
126 1
    }
127
128
    /**
129
     * @return Node[]
130
     */
131 1
    public function iterateNodes()
132
    {
133 1
        foreach ($this->nodes as $node) {
134 1
            yield $node;
135
        }
136 1
    }
137
138
    /**
139
     * @param eRecordType|null $type
140
     * @return Record[]
141
     */
142 1
    public function iterateRecords(eRecordType $type = NULL)
143
    {
144 1
        foreach ($this->iterateNodes() as $node) {
145 1
            foreach ($node->iterateRecords($type) as $record) {
146 1
                yield $record;
147
            }
148
        }
149 1
    }
150
151
    /**
152
     * @return array
153
     */
154 1
    public function toArray() : array
155
    {
156 1
        $records = [];
157 1
        foreach ($this->iterateRecords() as $record) {
158 1
            $records[] = $record->toArray();
159
        }
160
161 1
        return $records;
162
    }
163
164
    /**
165
     * @return array
166
     */
167
    public function getNodeNames() : array
168
    {
169
        return array_keys($this->nodes);
170
    }
171
172
    /**
173
     * @param $name
174
     * @return Node
175
     */
176 1
    public function getNode(string $name) : Node
177
    {
178 1
        $name = mb_strtolower(trim($name));
179
180 1
        if (!$this->isNodeExist($name)) {
181 1
            $this->nodes[$name] = new Node($this, $name);
182
        }
183
184 1
        return $this->nodes[$name];
185
    }
186
187
    /**
188
     * Check is node by given name already exists
189
     *
190
     * @param $name
191
     * @return bool
192
     */
193 1
    public function isNodeExist($name) : bool
194
    {
195 1
        return array_key_exists(mb_strtolower(trim($name)), $this->nodes);
196
    }
197
198
    /**
199
     * Full validate zone via build in validators
200
     *
201
     * @return bool
202
     */
203 1
    public function validate() : bool
204
    {
205 1
        $errorsStore = $this->getErrorsStore();
206 1
        $errorsStore->clear();
207
208 1
        foreach ($this->iterateNodes() as $node) {
209
            /** @noinspection PhpInternalEntityUsedInspection */
210 1
            $node->validate();
211
        }
212
213 1
        if (!SoaNumberCheck::validate($this)) {
214
            $errorsStore->add(ValidationError::makeZoneError($this, eErrorCode::SOA_ERROR()));
215
        }
216
217 1
        if (!OriginValidator::validate($this->getOrigin())) {
218 1
            $errorsStore->add(ValidationError::makeZoneError($this, eErrorCode::WRONG_ORIGIN()));
219
        }
220
221 1
        return !$errorsStore->isHasErrors();
222
    }
223
224
    /**
225
     * @return ErrorsStore
226
     */
227 1
    public function getErrorsStore()
228
    {
229 1
        return $this->errorsStore;
230
    }
231
232
    /**
233
     * @return String
234
     */
235 1
    public function getOrigin() : string
236
    {
237 1
        return $this->origin;
238
    }
239
}