Completed
Branch master (f0bd78)
by Sam
04:24 queued 01:02
created

AlignedRdataFormatters   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 180
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 79
dl 0
loc 180
ccs 72
cts 72
cp 1
rs 10
c 4
b 0
f 0
wmc 14

7 Methods

Rating   Name   Duplication   Size   Complexity  
A SOA() 0 23 1
A TXT() 0 17 4
A RRSIG() 0 22 2
A APL() 0 11 2
A LOC() 0 20 2
A makeLine() 0 9 2
A getRdataFormatters() 0 8 1
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\APL;
18
use Badcow\DNS\Rdata\LOC;
19
use Badcow\DNS\Rdata\RRSIG;
20
use Badcow\DNS\Rdata\SOA;
21
use Badcow\DNS\Rdata\TXT;
22
23
class AlignedRdataFormatters
24
{
25
    public static $rdataFormatters = [
26
        SOA::TYPE => __CLASS__.'::SOA',
27
        APL::TYPE => __CLASS__.'::APL',
28
        LOC::TYPE => __CLASS__.'::LOC',
29
        RRSIG::TYPE => __CLASS__.'::RRSIG',
30
        TXT::TYPE => __CLASS__.'::TXT',
31
    ];
32
33
    /**
34
     * @return callable[]
35
     */
36 3
    public static function getRdataFormatters(): array
37
    {
38
        return [
39 3
            SOA::TYPE => __CLASS__.'::SOA',
40 3
            APL::TYPE => __CLASS__.'::APL',
41
            LOC::TYPE => __CLASS__.'::LOC',
42
            RRSIG::TYPE => __CLASS__.'::RRSIG',
43
            TXT::TYPE => __CLASS__.'::TXT',
44
        ];
45
    }
46
47
    /**
48
     * @param SOA $rdata
49
     * @param int $padding
50
     *
51
     * @return string
52
     */
53 3
    public static function SOA(SOA $rdata, int $padding): string
54
    {
55
        $vars = [
56 3
            $rdata->getMname(),
57 3
            $rdata->getRname(),
58 3
            $rdata->getSerial(),
59 3
            $rdata->getRefresh(),
60 3
            $rdata->getRetry(),
61 3
            $rdata->getExpire(),
62 3
            $rdata->getMinimum(),
63
        ];
64
65 3
        $longestVarLength = max(array_map('strlen', $vars));
66
67
        return Tokens::OPEN_BRACKET.Tokens::LINE_FEED.
68 3
            self::makeLine((string) $rdata->getMname(), 'MNAME', $longestVarLength, $padding).
69 3
            self::makeLine((string) $rdata->getRname(), 'RNAME', $longestVarLength, $padding).
70 3
            self::makeLine((string) $rdata->getSerial(), 'SERIAL', $longestVarLength, $padding).
71 3
            self::makeLine((string) $rdata->getRefresh(), 'REFRESH', $longestVarLength, $padding).
72 3
            self::makeLine((string) $rdata->getRetry(), 'RETRY', $longestVarLength, $padding).
73 3
            self::makeLine((string) $rdata->getExpire(), 'EXPIRE', $longestVarLength, $padding).
74 3
            self::makeLine((string) $rdata->getMinimum(), 'MINIMUM', $longestVarLength, $padding).
75 3
            str_repeat(' ', $padding).Tokens::CLOSE_BRACKET;
76
    }
77
78
    /**
79
     * @param APL $rdata
80
     * @param int $padding
81
     *
82
     * @return string
83
     */
84 1
    public static function APL(APL $rdata, int $padding): string
85
    {
86 1
        $blocks = explode(' ', $rdata->toText());
87 1
        $longestVarLength = max(array_map('strlen', $blocks));
88 1
        $string = Tokens::OPEN_BRACKET.Tokens::LINE_FEED;
89
90 1
        foreach ($blocks as $block) {
91 1
            $string .= self::makeLine($block, null, $longestVarLength, $padding);
92
        }
93
94 1
        return $string.str_repeat(' ', $padding).Tokens::CLOSE_BRACKET;
95
    }
96
97
    /**
98
     * Split the TXT string into 40 character lines if the string is larger than 50 characters.
99
     *
100
     * @param TXT $txt
101
     * @param int $padding
102
     *
103
     * @return string
104
     */
105 1
    public static function TXT(TXT $txt, int $padding): string
106
    {
107 1
        if (null === $txt->getText() || strlen($txt->getText()) <= 50) {
108 1
            return $txt->toText();
109
        }
110
111 1
        $lines = str_split($txt->getText(), 40);
112 1
        $padString = str_repeat(Tokens::SPACE, $padding);
113
114 1
        $rdata = Tokens::OPEN_BRACKET.Tokens::SPACE;
115 1
        foreach ($lines as $line) {
116 1
            $rdata .= Tokens::LINE_FEED.$padString.Tokens::SPACE.Tokens::SPACE.
117 1
                Tokens::DOUBLE_QUOTES.$line.Tokens::DOUBLE_QUOTES;
118
        }
119 1
        $rdata .= Tokens::LINE_FEED.$padString.Tokens::CLOSE_BRACKET;
120
121 1
        return $rdata;
122
    }
123
124
    /**
125
     * Splits the RRSIG Signature into 32 character chunks.
126
     *
127
     * @param RRSIG $rrsig
128
     * @param int   $padding
129
     *
130
     * @return string
131
     */
132 1
    public static function RRSIG(RRSIG $rrsig, int $padding): string
133
    {
134 1
        $strPadding = str_repeat(Tokens::SPACE, $padding);
135 1
        $signatureParts = str_split($rrsig->getSignature(), 32);
136
137 1
        $rdata = $rrsig->getTypeCovered().Tokens::SPACE.
138 1
            $rrsig->getAlgorithm().Tokens::SPACE.
139 1
            $rrsig->getLabels().Tokens::SPACE.
140 1
            $rrsig->getOriginalTtl().Tokens::SPACE.Tokens::OPEN_BRACKET.Tokens::LINE_FEED.
141 1
            $strPadding.
142 1
            $rrsig->getSignatureExpiration()->format(RRSIG::TIME_FORMAT).Tokens::SPACE.
143 1
            $rrsig->getSignatureInception()->format(RRSIG::TIME_FORMAT).Tokens::SPACE.
144 1
            $rrsig->getKeyTag().Tokens::SPACE.
145 1
            $rrsig->getSignersName();
146
147 1
        foreach ($signatureParts as $line) {
148 1
            $rdata .= Tokens::LINE_FEED.$strPadding.$line;
149
        }
150
151 1
        $rdata .= Tokens::SPACE.Tokens::CLOSE_BRACKET;
152
153 1
        return $rdata;
154
    }
155
156
    /**
157
     * @param LOC $loc
158
     * @param int $padding
159
     *
160
     * @return string
161
     */
162 3
    public static function LOC(LOC $loc, int $padding): string
163
    {
164
        $parts = [
165 3
            'LATITUDE' => (string) $loc->getLatitude(LOC::FORMAT_DMS),
166 3
            'LONGITUDE' => (string) $loc->getLongitude(LOC::FORMAT_DMS),
167 3
            'ALTITUDE' => sprintf('%.2fm', $loc->getAltitude()),
168 3
            'SIZE' => sprintf('%.2fm', $loc->getSize()),
169 3
            'HORIZONTAL PRECISION' => sprintf('%.2fm', $loc->getHorizontalPrecision()),
170 3
            'VERTICAL PRECISION' => sprintf('%.2fm', $loc->getVerticalPrecision()),
171
        ];
172
173 3
        $longestVarLength = max(array_map('strlen', $parts));
174 3
        $rdata = Tokens::OPEN_BRACKET.Tokens::LINE_FEED;
175
176 3
        foreach ($parts as $comment => $text) {
177 3
            $rdata .= self::makeLine($text, $comment, $longestVarLength, $padding);
178
        }
179 3
        $rdata .= str_repeat(Tokens::SPACE, $padding).Tokens::CLOSE_BRACKET;
180
181 3
        return $rdata;
182
    }
183
184
    /**
185
     * Returns a padded line with comment.
186
     *
187
     * @param string $text
188
     * @param string $comment
189
     * @param int    $longestVarLength
190
     * @param int    $padding
191
     *
192
     * @return string
193
     */
194 3
    public static function makeLine(string $text, ?string $comment, int $longestVarLength, int $padding): string
195
    {
196 3
        $output = str_repeat(Tokens::SPACE, $padding).str_pad($text, $longestVarLength);
197
198 3
        if (null !== $comment) {
199 3
            $output .= Tokens::SPACE.Tokens::SEMICOLON.Tokens::SPACE.$comment;
200
        }
201
202 3
        return $output.Tokens::LINE_FEED;
203
    }
204
}
205