Passed
Push — master ( d57fc8...abd889 )
by Sam
57s queued 11s
created

ZoneBuilder::fillOutSrv()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
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\Parser\Tokens;
17
use Badcow\DNS\Rdata\AAAA;
18
use Badcow\DNS\Rdata\CNAME;
19
use Badcow\DNS\Rdata\DNAME;
20
use Badcow\DNS\Rdata\MX;
21
use Badcow\DNS\Rdata\NS;
22
use Badcow\DNS\Rdata\PTR;
23
use Badcow\DNS\Rdata\RdataInterface;
24
use Badcow\DNS\Rdata\SOA;
25
use Badcow\DNS\Rdata\SRV;
26
27
class ZoneBuilder
28
{
29
    /**
30
     * @param Zone $zone
31
     *
32
     * @return string
33
     */
34 3
    public static function build(Zone $zone): string
35
    {
36 3
        $master = '$ORIGIN '.$zone->getName().Tokens::LINE_FEED;
37 3
        if (null !== $zone->getDefaultTtl()) {
0 ignored issues
show
introduced by
The condition null !== $zone->getDefaultTtl() is always true.
Loading history...
38 3
            $master .= '$TTL '.$zone->getDefaultTtl().Tokens::LINE_FEED;
39
        }
40
41 3
        foreach ($zone as $rr) {
42 3
            if (null !== $rr->getRdata()) {
43 3
                $master .= preg_replace('/\s+/', ' ', trim(sprintf('%s %s %s %s %s',
44 3
                    $rr->getName(),
45 3
                    $rr->getTtl(),
46 3
                    $rr->getClass(),
47 3
                    $rr->getType(),
48 3
                    $rr->getRdata()->toText()
49
                )));
50
            }
51
52 3
            if (null !== $rr->getComment()) {
53 1
                $master .= '; '.$rr->getComment();
54
            }
55
56 3
            $master .= Tokens::LINE_FEED;
57
        }
58
59 3
        return $master;
60
    }
61
62
    /**
63
     * Fills out all of the data of each resource record. The function will add the parent domain to all non-qualified
64
     * sub-domains, replace '@' with the zone name, ensure the class and TTL are on each record.
65
     *
66
     * @param Zone $zone
67
     */
68 1
    public static function fillOutZone(Zone $zone): void
69
    {
70 1
        $class = $zone->getClass();
71
72 1
        foreach ($zone as &$rr) {
73 1
            $rr->setName(self::fullyQualify($rr->getName(), $zone->getName()));
74 1
            $rr->setTtl($rr->getTtl() ?? $zone->getDefaultTtl());
75 1
            $rr->setClass($class);
76 1
            $rdata = $rr->getRdata();
77 1
            static::fillOutRdata($rdata, $zone);
78
        }
79 1
    }
80
81
    /**
82
     * Add the parent domain to the sub-domain if the sub-domain if it is not fully qualified.
83
     *
84
     * @param string|null $subDomain
85
     * @param string      $parent
86
     *
87
     * @return string
88
     */
89 1
    protected static function fullyQualify(?string $subDomain, string $parent): string
90
    {
91 1
        if ('@' === $subDomain || null === $subDomain) {
92 1
            return $parent;
93
        }
94
95 1
        if ('.' !== substr($subDomain, -1, 1)) {
96 1
            return $subDomain.'.'.$parent;
97
        }
98
99 1
        return $subDomain;
100
    }
101
102
    /**
103
     * @param RdataInterface $rdata
104
     * @param Zone           $zone
105
     */
106 1
    protected static function fillOutRdata(RdataInterface $rdata, Zone $zone): void
107
    {
108
        $mappings = [
109 1
            SOA::TYPE => 'static::fillOutSoa',
110
            CNAME::TYPE => 'static::fillOutCname',
111
            DNAME::TYPE => 'static::fillOutCname',
112
            SRV::TYPE => 'static::fillOutSrv',
113
            NS::TYPE => 'static::fillOutCname',
114
            PTR::TYPE => 'static::fillOutCname',
115
            MX::TYPE => 'static::fillOutMx',
116
            AAAA::TYPE => 'static::fillOutAaaa',
117
        ];
118
119 1
        if (!array_key_exists($rdata->getType(), $mappings)) {
120 1
            return;
121
        }
122
123
        /** @var callable $callable */
124 1
        $callable = $mappings[$rdata->getType()];
125 1
        call_user_func($callable, $rdata, $zone);
126 1
    }
127
128
    /**
129
     * @param SOA  $rdata
130
     * @param Zone $zone
131
     */
132 1
    protected static function fillOutSoa(SOA $rdata, Zone $zone): void
133
    {
134 1
        $rdata->setMname(self::fullyQualify($rdata->getMname(), $zone->getName()));
135 1
        $rdata->setRname(self::fullyQualify($rdata->getRname(), $zone->getName()));
136 1
    }
137
138
    /**
139
     * @param CNAME $rdata
140
     * @param Zone  $zone
141
     */
142 1
    protected static function fillOutCname(Cname $rdata, Zone $zone): void
143
    {
144 1
        $rdata->setTarget(self::fullyQualify($rdata->getTarget(), $zone->getName()));
145 1
    }
146
147
    /**
148
     * @param SRV  $rdata
149
     * @param Zone $zone
150
     */
151
    protected static function fillOutSrv(SRV $rdata, Zone $zone): void
152
    {
153
        $rdata->setTarget(self::fullyQualify($rdata->getTarget(), $zone->getName()));
154
    }
155
156
    /**
157
     * @param MX   $rdata
158
     * @param Zone $zone
159
     */
160 1
    protected static function fillOutMx(MX $rdata, Zone $zone): void
161
    {
162 1
        $rdata->setExchange(self::fullyQualify($rdata->getExchange(), $zone->getName()));
163 1
    }
164
165
    /**
166
     * @param AAAA $rdata
167
     */
168 1
    protected static function fillOutAaaa(AAAA $rdata): void
169
    {
170 1
        $rdata->setAddress(PTR::expandIpv6($rdata->getAddress() ?? ''));
171 1
    }
172
}
173