Completed
Push — master ( 282f78...6dce89 )
by Sam
05:20
created

SystemResolver::extractPhpRdata()   B

Complexity

Conditions 10
Paths 10

Size

Total Lines 40
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 34
nc 10
nop 1
dl 0
loc 40
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * This file is part of PHP DNS Server.
4
 *
5
 * (c) Yif Swery <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace yswery\DNS\Resolver;
12
13
use yswery\DNS\UnsupportedTypeException;
14
use yswery\DNS\ResourceRecord;
15
use yswery\DNS\RecordTypeEnum;
16
17
/**
18
 * Use the host system's configured DNS.
19
 */
20
class SystemResolver extends AbstractResolver
21
{
22
    /**
23
     * SystemResolver constructor.
24
     *
25
     * @param bool $recursionAvailable
26
     * @param bool $authoritative
27
     */
28
    public function __construct($recursionAvailable = true, $authoritative = false)
29
    {
30
        $this->allowRecursion = (bool) $recursionAvailable;
31
        $this->isAuthoritative = (bool) $authoritative;
32
    }
33
34
    /**
35
     * @param ResourceRecord[] $question
36
     *
37
     * @return ResourceRecord[]
38
     *
39
     * @throws UnsupportedTypeException
40
     */
41
    public function getAnswer(array $question): array
42
    {
43
        $answer = [];
44
        $query = $question[0];
45
46
        $records = $this->getRecordsRecursively($query->getName(), $query->getType());
47
        foreach ($records as $record) {
48
            $answer[] = (new ResourceRecord())
49
                ->setName($query->getName())
50
                ->setClass($query->getClass())
51
                ->setTtl($record['ttl'])
52
                ->setRdata($record['rdata'])
53
                ->setType($query->getType());
54
        }
55
56
        return $answer;
57
    }
58
59
    /**
60
     * @param $domain
61
     * @param $type
62
     *
63
     * @return array
64
     *
65
     * @throws UnsupportedTypeException
66
     */
67
    private function getRecordsRecursively($domain, $type): array
68
    {
69
        if (false === $php_dns_type = $this->IANA2PHP($type)) {
0 ignored issues
show
introduced by
The condition false === $php_dns_type = $this->IANA2PHP($type) is always false.
Loading history...
70
            throw new UnsupportedTypeException(sprintf('Record type "%s" is not a supported type.', $type));
71
        }
72
73
        $records = dns_get_record($domain, $php_dns_type);
74
        $result = [];
75
76
        foreach ($records as $record) {
77
            $result[] = [
78
                'rdata' => $this->extractPhpRdata($record),
79
                'ttl' => $record['ttl'],
80
            ];
81
        }
82
83
        return $result;
84
    }
85
86
    /**
87
     * @param array  $resourceRecord
88
     * @param int    $type
89
     * @param string $parent
90
     *
91
     * @return array|mixed
92
     *
93
     * @throws UnsupportedTypeException
94
     */
95
    protected function extractPhpRdata(array $resourceRecord)
96
    {
97
        $type = RecordTypeEnum::getTypeIndex($resourceRecord['type']);
98
99
        switch ($type) {
100
            case RecordTypeEnum::TYPE_A:
101
                return $resourceRecord['ip'];
102
            case RecordTypeEnum::TYPE_AAAA:
103
                return $resourceRecord['ipv6'];
104
            case RecordTypeEnum::TYPE_NS:
105
            case RecordTypeEnum::TYPE_CNAME:
106
            case RecordTypeEnum::TYPE_PTR:
107
                return $resourceRecord['target'];
108
            case RecordTypeEnum::TYPE_SOA:
109
                return [
110
                        'mname' => $resourceRecord['mname'],
111
                        'rname' => $resourceRecord['rname'],
112
                        'serial' => $resourceRecord['serial'],
113
                        'refresh' => $resourceRecord['refresh'],
114
                        'retry' => $resourceRecord['retry'],
115
                        'expire' => $resourceRecord['expire'],
116
                        'minimum' => $resourceRecord['minimum-ttl'],
117
                    ];
118
            case RecordTypeEnum::TYPE_MX:
119
                return [
120
                    'preference' => $resourceRecord['pri'],
121
                    'exchange' => $resourceRecord['host'],
122
                ];
123
            case RecordTypeEnum::TYPE_TXT:
124
                return $resourceRecord['txt'];
125
            case RecordTypeEnum::TYPE_SRV:
126
                return [
127
                    'priority' => $resourceRecord['pri'],
128
                    'port' => $resourceRecord['port'],
129
                    'weight' => $resourceRecord['weight'],
130
                    'target' => $resourceRecord['target'],
131
                ];
132
            default:
133
                throw new UnsupportedTypeException(
134
                    sprintf('Record type "%s" is not a supported type.', RecordTypeEnum::getName($type))
0 ignored issues
show
Bug introduced by
It seems like $type can also be of type false; however, parameter $type of yswery\DNS\RecordTypeEnum::getName() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

134
                    sprintf('Record type "%s" is not a supported type.', RecordTypeEnum::getName(/** @scrutinizer ignore-type */ $type))
Loading history...
135
                );
136
        }
137
    }
138
139
    /**
140
     * Maps an IANA Rdata type to the built-in PHP DNS constant.
141
     *
142
     * @example $this->IANA_to_PHP(5) //Returns DNS_CNAME int(16)
143
     *
144
     * @param int $type the IANA RTYPE
145
     *
146
     * @return int|bool the built in PHP DNS_<type> constant
147
     */
148
    private function IANA2PHP(int $type): int
149
    {
150
        $constantName = 'DNS_'.RecordTypeEnum::getName($type);
151
152
        return defined($constantName) ? constant($constantName) : false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return defined($constant...($constantName) : false could return the type false which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
153
    }
154
}
155