Passed
Push — master ( a21ca3...043ecc )
by Sergey
02:54
created

Node::notify()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.7898

Importance

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