ResourceRecord   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 231
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 27
lcom 1
cbo 6
dl 0
loc 231
ccs 81
cts 81
cp 1
rs 10
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 11 1
A setClass() 0 14 4
A setName() 0 4 1
A setRdata() 0 4 1
A getClass() 0 8 2
A setClassId() 0 4 1
A getClassId() 0 4 1
A setTtl() 0 4 1
A getName() 0 4 1
A getType() 0 8 2
A getRdata() 0 4 1
A getTtl() 0 4 1
A setComment() 0 4 1
A getComment() 0 4 1
B toWire() 0 35 6
A fromWire() 0 17 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Badcow DNS Library.
7
 *
8
 * (c) Samuel Williams <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Badcow\DNS;
15
16
use Badcow\DNS\Rdata\A;
17
use Badcow\DNS\Rdata\DecodeException;
18
use Badcow\DNS\Rdata\Factory;
19
use Badcow\DNS\Rdata\RdataInterface;
20
use InvalidArgumentException;
21
22
class ResourceRecord
23
{
24
    /**
25
     * @var int|null
26
     */
27
    private $classId = 1;
28
29
    /**
30
     * @var RdataInterface|null
31
     */
32
    private $rdata;
33
34
    /**
35
     * @var int|null
36
     */
37
    private $ttl;
38
39
    /**
40
     * @var string
41
     */
42
    private $name;
43
44
    /**
45
     * @var string|null
46
     */
47
    private $comment;
48
49
    /**
50
     * @param int    $ttl
51
     * @param string $comment
52 16
     */
53
    public static function create(string $name, RdataInterface $rdata, int $ttl = null, string $class = Classes::INTERNET, string $comment = null): ResourceRecord
54 16
    {
55 16
        $rr = new self();
56 16
        $rr->setName($name);
57 16
        $rr->setRdata($rdata);
58 16
        $rr->setTtl($ttl);
59 16
        $rr->setClass($class);
60
        $rr->setComment($comment);
61 16
62
        return $rr;
63
    }
64
65
    /**
66
     * Set the class for the resource record
67
     * Usually one of IN, HS, or CH.
68
     *
69
     * @param string $class
70
     *
71
     * @throws InvalidArgumentException
72 45
     */
73
    public function setClass(?string $class): void
74 45
    {
75 1
        if (null !== $class && !Classes::isValid($class)) {
76
            throw new InvalidArgumentException(sprintf('No such class as "%s"', $class));
77
        }
78 45
79 1
        if (null === $class) {
80
            $this->classId = null;
81 1
82
            return;
83
        }
84 45
85 45
        $this->classId = Classes::getClassId($class);
86
    }
87
88
    /**
89
     * Set the name for the resource record.
90
     * Eg. "subdomain.example.com.".
91 54
     */
92
    public function setName(string $name): void
93 54
    {
94 54
        $this->name = $name;
95
    }
96
97
    /**
98
     * @param RdataInterface $rdata
99 51
     */
100
    public function setRdata(?RdataInterface $rdata): void
101 51
    {
102 51
        $this->rdata = $rdata;
103
    }
104
105
    /**
106
     * @return string
107 40
     */
108
    public function getClass(): ?string
109 40
    {
110 1
        if (null === $this->classId) {
111
            return null;
112
        }
113 39
114
        return Classes::getClassName($this->classId);
115
    }
116 8
117
    public function setClassId(int $classId): void
118 8
    {
119 8
        $this->classId = $classId;
120
    }
121 2
122
    public function getClassId(): ?int
123 2
    {
124
        return $this->classId;
125
    }
126
127
    /**
128
     * Set the time to live.
129
     *
130
     * @param int $ttl
131 54
     */
132
    public function setTtl(?int $ttl): void
133 54
    {
134 54
        $this->ttl = $ttl;
135
    }
136
137
    /**
138
     * @return string
139 39
     */
140
    public function getName(): ?string
141 39
    {
142
        return $this->name;
143
    }
144
145
    /**
146
     * @return string
147 29
     */
148
    public function getType(): ?string
149 29
    {
150 2
        if (null === $this->rdata) {
151
            return null;
152
        }
153 28
154
        return $this->rdata->getType();
155
    }
156
157
    /**
158
     * @return RdataInterface
159 33
     */
160
    public function getRdata(): ?RdataInterface
161 33
    {
162
        return $this->rdata;
163
    }
164
165
    /**
166
     * @return int
167 36
     */
168
    public function getTtl(): ?int
169 36
    {
170
        return $this->ttl;
171
    }
172
173
    /**
174
     * Set a comment for the record.
175
     *
176
     * @param string $comment
177 45
     */
178
    public function setComment(?string $comment): void
179 45
    {
180 45
        $this->comment = $comment;
181
    }
182
183
    /**
184
     * Get the record's comment.
185
     *
186
     * @return string
187 13
     */
188
    public function getComment(): ?string
189 13
    {
190
        return $this->comment;
191
    }
192
193
    /**
194
     * @throws UnsetValueException|InvalidArgumentException
195 8
     */
196
    public function toWire(): string
197 8
    {
198 1
        if (null === $this->name) {
199
            throw new UnsetValueException('ResourceRecord name has not been set.');
200
        }
201 7
202 1
        if (null === $this->rdata) {
203
            throw new UnsetValueException('ResourceRecord rdata has not been set.');
204
        }
205 6
206 1
        if (null === $this->classId) {
207
            throw new UnsetValueException('ResourceRecord class has not been set.');
208
        }
209 5
210 1
        if (null === $this->ttl) {
211
            throw new UnsetValueException('ResourceRecord TTL has not been set.');
212
        }
213 4
214 1
        if (!Validator::fullyQualifiedDomainName($this->name)) {
215
            throw new InvalidArgumentException(sprintf('"%s" is not a fully qualified domain name.', $this->name));
216
        }
217 3
218
        $rdata = $this->rdata->toWire();
219 3
220 3
        $encoded = Message::encodeName($this->name);
221 3
        $encoded .= pack('nnNn',
222 3
            $this->rdata->getTypeCode(),
223 3
            $this->classId,
224 3
            $this->ttl,
225
            strlen($rdata)
226 3
        );
227
        $encoded .= $rdata;
228 3
229
        return $encoded;
230
    }
231
232
    /**
233
     * @throws Rdata\UnsupportedTypeException
234 8
     */
235
    public static function fromWire(string $encoded, int &$offset = 0): ResourceRecord
236 8
    {
237 8
        $rr = new self();
238 8
        $rr->setName(Message::decodeName($encoded, $offset));
239 8
        if (false === $integers = unpack('ntype/nclass/Nttl/ndlength', $encoded, $offset)) {
240 8
            throw new \UnexpectedValueException(sprintf('Malformed resource record encountered. "%s"', DecodeException::binaryToHex($encoded)));
241 8
        }
242 8
        $offset += 10;
243 8
        $rr->setClassId($integers['class']);
244 8
        $rr->setTtl($integers['ttl']);
245 8
        $rdLength = $integers['dlength'];
246
        $rdata = Factory::newRdataFromId($integers['type']);
247 8
        $rdata->fromWire($encoded, $offset, $rdLength);
248
        $rr->setRdata($rdata);
249
250
        return $rr;
251
    }
252
}
253