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

AlignedRdataFormatters::TXT()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 10.1554

Importance

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