Passed
Push — master ( 3f3f7b...ddf05f )
by Sergey
02:41
created

Node::iterateRecords()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 3
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\zoneEntities;
9
10
use LTDBeget\dns\configurator\errors\ValidationError;
11
use LTDBeget\dns\configurator\traits\RecordsIterateTrait;
12
use LTDBeget\dns\configurator\validators\CnameNumberCheck;
13
use LTDBeget\dns\configurator\validators\ConflictTypesValidator;
14
use LTDBeget\dns\configurator\validators\NodeNameValidator;
15
use LTDBeget\dns\configurator\validators\NoSoaRecordValidator;
16
use LTDBeget\dns\configurator\validators\SoaNumberCheck;
17
use LTDBeget\dns\configurator\Zone;
18
use LTDBeget\dns\configurator\zoneEntities\record\base\Record;
19
use LTDBeget\dns\enums\eErrorCode;
20
use LTDBeget\dns\enums\eRecordNotification;
21
use LTDBeget\dns\enums\eRecordType;
22
23
/**
24
 * Class Node
25
 *
26
 * @package LTDBeget\dns\configurator\zoneEntities
27
 */
28
class Node
29
{
30
    use RecordsIterateTrait;
31
32
    /**
33
     * @var Zone
34
     */
35
    private $zone;
36
    /**
37
     * @var string
38
     */
39
    private $name;
40
    /**
41
     * @var RecordAppender
42
     */
43
    private $recordAppender;
44
    /**
45
     * @var RecordsStore
46
     */
47
    private $recordsStore;
48
    /**
49
     * @var RecordsStore
50
     */
51
    private $removedRecordsStore;
52
53
    /**
54
     * @param Zone $zone
55
     * @param      $name
56
     */
57 1
    public function __construct(Zone $zone, string $name)
58
    {
59 1
        $this->zone                = $zone;
60 1
        $this->name                = mb_strtolower(trim($name));
61 1
        $this->recordAppender      = new RecordAppender($this);
62 1
        $this->recordsStore        = new RecordsStore();
63 1
        $this->removedRecordsStore = new RecordsStore();
64 1
    }
65
66
    /**
67
     * @return RecordAppender
68
     */
69 1
    public function getRecordAppender() : RecordAppender
70
    {
71 1
        return $this->recordAppender;
72
    }
73
74
    /**
75
     * @return Record[]
76
     */
77
    public function iterateRemoved()
78
    {
79
        foreach ($this->getRemovedRecordsStore()->iterate() as $record) {
80
            yield $record;
81
        }
82
    }
83
84
    /**
85
     * @return RecordsStore
86
     */
87
    protected function getRemovedRecordsStore()
88
    {
89
        return $this->removedRecordsStore;
90
    }
91
92
    /**
93
     * @param eRecordType|null $type
94
     * @return Record[]
95
     */
96 1
    public function iterateRecords(eRecordType $type = NULL)
97
    {
98 1
        foreach ($this->getRecordsStore()->iterate($type) as $record) {
99 1
            yield $record;
100
        }
101 1
    }
102
103
    /**
104
     * @param eRecordType|NULL $type
105
     */
106
    public function removeRecords(eRecordType $type = NULL)
107
    {
108
        foreach ($this->iterateRecords($type) as $record) {
109
            $record->remove();
110
        }
111
    }
112
113
    /**
114
     * @return bool
115
     */
116
    public function isEmptyNode() : bool
117
    {
118
        return $this->getRecordsStore()->count() === 0;
119
    }
120
121
    /**
122
     * @return RecordsStore
123
     */
124 1
    protected function getRecordsStore() : RecordsStore
125
    {
126 1
        return $this->recordsStore;
127
    }
128
129
    /**
130
     * @internal
131
     * @param Record              $record
132
     * @param eRecordNotification $notification
133
     * @return Node
134
     */
135 1
    public function notify(Record $record, eRecordNotification $notification) : Node
136
    {
137
        switch ($notification) {
138 1
            case eRecordNotification::ADD:
139 1
                $this->recordsStore->append($record);
140 1
                break;
141
            case eRecordNotification::REMOVE:
142
                $this->recordsStore->remove($record);
143
                $this->removedRecordsStore->append($record);
144
                break;
145
            case eRecordNotification::CHANGE:
146
                $this->getRecordsStore()->change($record);
147
                break;
148
        }
149
150 1
        return $this;
151
    }
152
153 1
    public function sort()
154
    {
155 1
        $this->getRecordsStore()->sort();
156 1
    }
157
158
    /**
159
     * @internal
160
     * Full validate zone via build in validators
161
     * @return bool
162
     */
163 1
    public function validate() : bool
164
    {
165 1
        $errorsStore = $this->getZone()->getErrorsStore();
166
167 1
        if (!ConflictTypesValidator::validate($this)) {
168
            $errorsStore->add(ValidationError::makeNodeError($this, eErrorCode::CONFLICT_RECORD_TYPES_ERROR()));
169
        }
170
171 1
        if (!CnameNumberCheck::validate($this)) {
172
            $errorsStore->add(ValidationError::makeNodeError($this, eErrorCode::MULTIPLE_CNAME_ERROR()));
173
        }
174
175 1
        if (!NodeNameValidator::validate($this->getName())) {
176
            $errorsStore->add(ValidationError::makeNodeError($this, eErrorCode::WRONG_NODE_NAME()));
177
        }
178
        
179 1
        if ($this->getName() === "@"  && (!SoaNumberCheck::validate($this) || !NoSoaRecordValidator::validate($this))) {
180 1
            $errorsStore->add(ValidationError::makeNodeError($this, eErrorCode::SOA_ERROR()));
181
        }
182
183 1
        if ($this->getName() !== "@" && SoaNumberCheck::validate($this)) {
184
            $errorsStore->add(ValidationError::makeNodeError($this, eErrorCode::SOA_ERROR()));
185
        }
186
187 1
        foreach ($this->iterateRecords() as $record) {
188
            /** @noinspection PhpInternalEntityUsedInspection */
189 1
            $record->validate();
190
        }
191
192 1
        return !$errorsStore->isHasErrors();
193
    }
194
195
    /**
196
     * @return Zone
197
     */
198 1
    public function getZone() : Zone
199
    {
200 1
        return $this->zone;
201
    }
202
203
    /**
204
     * @return string
205
     */
206 1
    public function getName() : string
207
    {
208 1
        return $this->name;
209
    }
210
}