Passed
Push — master ( bb44e9...3f3f7b )
by Sergey
02:48
created

Zone::sort()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4
Metric Value
dl 0
loc 19
ccs 12
cts 12
cp 1
rs 9.2
cc 4
eloc 11
nc 6
nop 0
crap 4
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\base\Record;
19
use LTDBeget\dns\enums\eErrorCode;
20
use LTDBeget\dns\enums\eRecordType;
21
22
/**
23
 * Class Zone
24
 *
25
 * @package LTDBeget\dns\configurator
26
 */
27
class Zone
28
{
29
    use RecordsIterateTrait;
30
31
    /**
32
     * @var String
33
     */
34
    private $origin;
35
    /**
36
     * @var Node[] $nodes
37
     */
38
    private $nodes = [];
39
    /**
40
     * @var ErrorsStore
41
     */
42
    private $errorsStore;
43
44
    /**
45
     * @param $origin
46
     */
47 1
    public function __construct(string $origin)
48
    {
49 1
        $this->origin      = mb_strtolower(trim($origin));
50 1
        $this->errorsStore = new ErrorsStore();
51 1
    }
52
53
    /**
54
     * @param string $origin
55
     * @param string $plainData
56
     * @return Zone
57
     */
58 1
    public static function fromString(string $origin, string $plainData) : Zone
59
    {
60 1
        return PlainDeserializer::deserialize(new self($origin), $plainData);
61
    }
62
63
    /**
64
     * @param string $origin
65
     * @param array  $arrayData
66
     * @return Zone
67
     */
68
    public static function fromArray(string $origin, array $arrayData) : Zone
69
    {
70
        return ArrayDeserializer::deserialize(new self($origin), $arrayData);
71
    }
72
73
    /**
74
     * @return string
75
     */
76 1
    public function __toString() : string
77
    {
78 1
        $this->sort();
79 1
        $records = [];
80 1
        foreach ($this->iterateRecords() as $record) {
81 1
            $records[] = (string) $record;
82
        }
83
84 1
        return implode("\n", $records);
85
    }
86
87
    /**
88
     * Sort zone by node names and record types
89
     */
90 1
    public function sort()
91
    {
92 1
        $nodes = $this->nodes;
93
        /** @var Node[] $_nodes */
94 1
        $_nodes = [];
95 1
        foreach (['@', 'www', '*'] as $node_name) {
96 1
            if (isset($nodes[$node_name])) {
97 1
                $_nodes[$node_name] = $nodes[$node_name];
98 1
                unset($nodes[$node_name]);
99
            }
100
        }
101
102 1
        ksort($nodes);
103 1
        $this->nodes = array_merge($_nodes, $nodes);
104
105 1
        foreach ($this->iterateNodes() as $node) {
106 1
            $node->sort();
107
        }
108 1
    }
109
110
    /**
111
     * @return Node[]
112
     */
113 1
    public function iterateNodes()
114
    {
115 1
        foreach ($this->nodes as $node) {
116 1
            yield $node;
117
        }
118 1
    }
119
120
    /**
121
     * @param eRecordType|null $type
122
     * @return Record[]
123
     */
124 1
    public function iterateRecords(eRecordType $type = NULL)
125
    {
126 1
        foreach ($this->iterateNodes() as $node) {
127 1
            foreach ($node->iterateRecords($type) as $record) {
128 1
                yield $record;
129
            }
130
        }
131 1
    }
132
133
    /**
134
     * @return array
135
     */
136 1
    public function toArray() : array
137
    {
138 1
        $records = [];
139 1
        foreach ($this->iterateRecords() as $record) {
140 1
            $records[] = $record->toArray();
141
        }
142
143 1
        return $records;
144
    }
145
146
    /**
147
     * @return array
148
     */
149
    public function getNodeNames() : array
150
    {
151
        return array_keys($this->nodes);
152
    }
153
154
    /**
155
     * @param $name
156
     * @return Node
157
     */
158 1
    public function getNode(string $name) : Node
159
    {
160 1
        $name = mb_strtolower(trim($name));
161
162 1
        if (!$this->isNodeExist($name)) {
163 1
            $this->nodes[$name] = new Node($this, $name);
164
        }
165
166 1
        return $this->nodes[$name];
167
    }
168
169
    /**
170
     * Check is node by given name already exists
171
     *
172
     * @param $name
173
     * @return bool
174
     */
175 1
    public function isNodeExist($name) : bool
176
    {
177 1
        return array_key_exists(mb_strtolower(trim($name)), $this->nodes);
178
    }
179
180
    /**
181
     * @param eRecordType|NULL $type
182
     */
183
    public function removeRecords(eRecordType $type = NULL)
184
    {
185
        foreach ($this->iterateNodes() as $node) {
186
            foreach ($node->iterateRecords($type) as $record) {
187
                $record->remove();
188
            }
189
        }
190
    }
191
192
    /**
193
     * @return bool
194
     */
195
    public function isEmptyZone() : bool
196
    {
197
        $result = true;
198
        foreach ($this->iterateNodes() as $node) {
199
            if(! $node->isEmptyNode()) {
200
                $result = false;
201
            }
202
        }
203
        return $result;
204
    }
205
206
    /**
207
     * Full validate zone via build in validators
208
     *
209
     * @return bool
210
     */
211 1
    public function validate() : bool
212
    {
213 1
        $errorsStore = $this->getErrorsStore();
214 1
        $errorsStore->clear();
215
216 1
        foreach ($this->iterateNodes() as $node) {
217
            /** @noinspection PhpInternalEntityUsedInspection */
218 1
            $node->validate();
219
        }
220
221 1
        if (!SoaNumberCheck::validate($this)) {
222
            $errorsStore->add(ValidationError::makeZoneError($this, eErrorCode::SOA_ERROR()));
223
        }
224
225 1
        if (!OriginValidator::validate($this->getOrigin())) {
226 1
            $errorsStore->add(ValidationError::makeZoneError($this, eErrorCode::WRONG_ORIGIN()));
227
        }
228
229 1
        return !$errorsStore->isHasErrors();
230
    }
231
232
    /**
233
     * @return ErrorsStore
234
     */
235 1
    public function getErrorsStore()
236
    {
237 1
        return $this->errorsStore;
238
    }
239
240
    /**
241
     * @return String
242
     */
243 1
    public function getOrigin() : string
244
    {
245 1
        return $this->origin;
246
    }
247
}