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

JsonResolver   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 44
dl 0
loc 105
rs 10
c 0
b 0
f 0
wmc 12

4 Methods

Rating   Name   Duplication   Size   Complexity  
A processZone() 0 20 3
A processLegacyZone() 0 20 4
A __construct() 0 10 3
A isLegacyFormat() 0 9 2
1
<?php
2
3
namespace yswery\DNS\Resolver;
4
5
use yswery\DNS\ClassEnum;
6
use yswery\DNS\RecordTypeEnum;
7
use yswery\DNS\ResourceRecord;
8
use yswery\DNS\UnsupportedTypeException;
9
10
class JsonResolver extends AbstractResolver
11
{
12
    /**
13
     * @var string
14
     */
15
    protected $defaultClass = ClassEnum::INTERNET;
16
17
    /**
18
     * @var int
19
     */
20
    protected $defaultTtl;
21
22
    /**
23
     * JsonResolver constructor.
24
     *
25
     * @param array $files
26
     * @param int   $defaultTtl
27
     *
28
     * @throws UnsupportedTypeException
29
     */
30
    public function __construct(array $files, $defaultTtl = 300)
31
    {
32
        $this->isAuthoritative = true;
33
        $this->allowRecursion = false;
34
        $this->defaultTtl = $defaultTtl;
35
36
        foreach ($files as $file) {
37
            $zone = json_decode(file_get_contents($file), true);
38
            $resourceRecords = $this->isLegacyFormat($zone) ? $this->processLegacyZone($zone) : $this->processZone($zone);
39
            $this->addZone($resourceRecords);
40
        }
41
    }
42
43
    /**
44
     * @param array $zone
45
     *
46
     * @return ResourceRecord[]
47
     *
48
     * @throws UnsupportedTypeException
49
     */
50
    protected function processZone(array $zone): array
51
    {
52
        $parent = rtrim($zone['domain'], '.').'.';
53
        $defaultTtl = $zone['default-ttl'];
54
        $rrs = $zone['resource-records'];
55
        $resourceRecords = [];
56
57
        foreach ($rrs as $rr) {
58
            $name = $rr['name'] ?? $parent;
59
            $class = isset($rr['class']) ? ClassEnum::getClassFromName($rr['class']) : $this->defaultClass;
60
61
            $resourceRecords[] = (new ResourceRecord())
62
                ->setName($this->handleName($name, $parent))
63
                ->setClass($class)
0 ignored issues
show
Bug introduced by
It seems like $class can also be of type string; however, parameter $class of yswery\DNS\ResourceRecord::setClass() 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

63
                ->setClass(/** @scrutinizer ignore-type */ $class)
Loading history...
64
                ->setType($type = RecordTypeEnum::getTypeIndex($rr['type']))
0 ignored issues
show
Bug introduced by
It seems like $type = yswery\DNS\Recor...tTypeIndex($rr['type']) can also be of type false; however, parameter $type of yswery\DNS\ResourceRecord::setType() 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

64
                ->setType(/** @scrutinizer ignore-type */ $type = RecordTypeEnum::getTypeIndex($rr['type']))
Loading history...
65
                ->setTtl($rr['ttl'] ?? $defaultTtl)
66
                ->setRdata($this->extractRdata($rr, $type, $parent));
0 ignored issues
show
Bug introduced by
It seems like $type can also be of type false; however, parameter $type of yswery\DNS\Resolver\Abst...esolver::extractRdata() 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

66
                ->setRdata($this->extractRdata($rr, /** @scrutinizer ignore-type */ $type, $parent));
Loading history...
67
        }
68
69
        return $resourceRecords;
70
    }
71
72
    /**
73
     * Determine if a $zone is in the legacy format.
74
     *
75
     * @param array $zone
76
     *
77
     * @return bool
78
     */
79
    protected function isLegacyFormat(array $zone): bool
80
    {
81
        $keys = array_map(function ($value) {
82
            return strtolower($value);
83
        }, array_keys($zone));
84
85
        return
86
            (false === array_search('domain', $keys, true)) ||
87
            (false === array_search('resource-records', $keys, true));
88
    }
89
90
    /**
91
     * @param array $zones
92
     *
93
     * @return ResourceRecord[]
94
     */
95
    protected function processLegacyZone(array $zones): array
96
    {
97
        $resourceRecords = [];
98
        foreach ($zones as $domain => $types) {
99
            $domain = rtrim($domain, '.').'.';
100
            foreach ($types as $type => $data) {
101
                $data = (array) $data;
102
                $type = RecordTypeEnum::getTypeIndex($type);
103
                foreach ($data as $rdata) {
104
                    $resourceRecords[] = (new ResourceRecord())
105
                        ->setName($domain)
106
                        ->setType($type)
0 ignored issues
show
Bug introduced by
It seems like $type can also be of type false; however, parameter $type of yswery\DNS\ResourceRecord::setType() 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

106
                        ->setType(/** @scrutinizer ignore-type */ $type)
Loading history...
107
                        ->setClass($this->defaultClass)
0 ignored issues
show
Bug introduced by
$this->defaultClass of type string is incompatible with the type integer expected by parameter $class of yswery\DNS\ResourceRecord::setClass(). ( Ignorable by Annotation )

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

107
                        ->setClass(/** @scrutinizer ignore-type */ $this->defaultClass)
Loading history...
108
                        ->setTtl($this->defaultTtl)
109
                        ->setRdata($rdata);
110
                }
111
            }
112
        }
113
114
        return $resourceRecords;
115
    }
116
}
117