Passed
Push — master ( 5cb917...3c1566 )
by Sergey
02:41
created

Node   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 179
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 63.33%
Metric Value
wmc 25
lcom 1
cbo 11
dl 0
loc 179
ccs 38
cts 60
cp 0.6333
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A getRecordAppender() 0 4 1
A iterateRemoved() 0 6 2
A getRemovedRecordsStore() 0 4 1
A iterateRecords() 0 6 2
A removeRecords() 0 6 2
A isEmptyNode() 0 4 1
A getRecordsStore() 0 4 1
A notify() 0 17 4
A sort() 0 4 1
A getZone() 0 4 1
A getName() 0 4 1
C validate() 0 27 7
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
     * @return Record[]
94
     */
95 1
    public function iterateRecords(eRecordType $type = NULL)
96
    {
97 1
        foreach ($this->getRecordsStore()->iterate($type) as $record) {
98 1
            yield $record;
99
        }
100 1
    }
101
102
    /**
103
     * @param eRecordType|NULL $type
104
     */
105
    public function removeRecords(eRecordType $type = NULL)
106
    {
107
        foreach ($this->iterateRecords($type) as $record) {
108
            $record->remove();
109
        }
110
    }
111
112
    /**
113
     * @return bool
114
     */
115
    public function isEmptyNode() : bool
116
    {
117
        return $this->getRecordsStore()->count() === 0;
118
    }
119
120
    /**
121
     * @return RecordsStore
122
     */
123 1
    protected function getRecordsStore() : RecordsStore
124
    {
125 1
        return $this->recordsStore;
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
            case eRecordNotification::CHANGE:
145
                $this->getRecordsStore()->change($record);
146
                break;
147
        }
148
149 1
        return $this;
150
    }
151
152 1
    public function sort()
153
    {
154 1
        $this->getRecordsStore()->sort();
155 1
    }
156
157
    /**
158
     * @internal
159
     * Full validate zone via build in validators
160
     * @return bool
161
     */
162 1
    public function validate() : bool
163
    {
164 1
        $errorsStore = $this->getZone()->getErrorsStore();
165
166 1
        if (!ConflictTypesValidator::validate($this)) {
167
            $errorsStore->add(ValidationError::makeNodeError($this, eErrorCode::CONFLICT_RECORD_TYPES_ERROR()));
168
        }
169
170 1
        if (!CnameNumberCheck::validate($this)) {
171
            $errorsStore->add(ValidationError::makeNodeError($this, eErrorCode::MULTIPLE_CNAME_ERROR()));
172
        }
173
174 1
        if ($this->getName() === "@" && ! SoaNumberCheck::validate($this)) {
175
            $errorsStore->add(ValidationError::makeNodeError($this, eErrorCode::SOA_ERROR()));
176
        }
177
178 1
        $isValidNodeName = DnsZoneDomainNameValidator::validate($this->getName());
179 1
        foreach ($this->iterateRecords() as $record) {
180 1
            if(!$isValidNodeName) {
181 1
                $errorsStore->add(ValidationError::makeRecordError($record, eErrorCode::WRONG_NODE_NAME(), "name"));
182
            }
183
            /** @noinspection PhpInternalEntityUsedInspection */
184 1
            $record->validate();
185
        }
186
187 1
        return !$errorsStore->isHasErrors();
188
    }
189
190
    /**
191
     * @return Zone
192
     */
193 1
    public function getZone() : Zone
194
    {
195 1
        return $this->zone;
196
    }
197
198
    /**
199
     * @return string
200
     */
201 1
    public function getName() : string
202
    {
203 1
        return $this->name;
204
    }
205
}