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

Node::__call()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 10
Ratio 100 %

Code Coverage

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