JsonResolver::processLegacyZone()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 14
nc 4
nop 1
dl 0
loc 20
ccs 15
cts 15
cp 1
crap 4
rs 9.7998
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of PHP DNS Server.
5
 *
6
 * (c) Yif Swery <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace yswery\DNS\Resolver;
13
14
use yswery\DNS\ClassEnum;
15
use yswery\DNS\RecordTypeEnum;
16
use yswery\DNS\ResourceRecord;
17
use yswery\DNS\UnsupportedTypeException;
18
19
class JsonResolver extends AbstractResolver
20
{
21
    /**
22
     * @var int
23
     */
24
    protected $defaultClass = ClassEnum::INTERNET;
25
26
    /**
27
     * @var int
28
     */
29
    protected $defaultTtl;
30
31
    /**
32
     * JsonResolver constructor.
33
     *
34
     * @param array $files
35
     * @param int   $defaultTtl
36
     *
37
     * @throws UnsupportedTypeException
38
     */
39 35
    public function __construct(array $files, $defaultTtl = 300)
40
    {
41 35
        $this->isAuthoritative = true;
42 35
        $this->allowRecursion = false;
43 35
        $this->defaultTtl = $defaultTtl;
44
45 35
        foreach ($files as $file) {
46 24
            $zone = json_decode(file_get_contents($file), true);
47 24
            $resourceRecords = $this->isLegacyFormat($zone) ? $this->processLegacyZone($zone) : $this->processZone($zone);
48 24
            $this->addZone($resourceRecords);
49
        }
50 35
    }
51
52
    /**
53
     * @param array $zone
54
     *
55
     * @return ResourceRecord[]
56
     *
57
     * @throws UnsupportedTypeException
58
     */
59 34
    protected function processZone(array $zone): array
60
    {
61 34
        $parent = rtrim($zone['domain'], '.').'.';
62 34
        $defaultTtl = $zone['default-ttl'];
63 34
        $rrs = $zone['resource-records'];
64 34
        $resourceRecords = [];
65
66 34
        foreach ($rrs as $rr) {
67 34
            $name = $rr['name'] ?? $parent;
68 34
            $class = isset($rr['class']) ? ClassEnum::getClassFromName($rr['class']) : $this->defaultClass;
69
70 34
            $resourceRecords[] = (new ResourceRecord())
71 34
                ->setName($this->handleName($name, $parent))
72 34
                ->setClass($class)
73 34
                ->setType($type = RecordTypeEnum::getTypeFromName($rr['type']))
74 34
                ->setTtl($rr['ttl'] ?? $defaultTtl)
75 34
                ->setRdata($this->extractRdata($rr, $type, $parent));
76
        }
77
78 34
        return $resourceRecords;
79
    }
80
81
    /**
82
     * Determine if a $zone is in the legacy format.
83
     *
84
     * @param array $zone
85
     *
86
     * @return bool
87
     */
88 34
    protected function isLegacyFormat(array $zone): bool
89
    {
90
        $keys = array_map(function ($value) {
91 34
            return strtolower($value);
92 34
        }, array_keys($zone));
93
94
        return
95 34
            (false === array_search('domain', $keys, true)) ||
96 34
            (false === array_search('resource-records', $keys, true));
97
    }
98
99
    /**
100
     * @param array $zones
101
     *
102
     * @return array
103
     */
104 34
    protected function processLegacyZone(array $zones): array
105
    {
106 34
        $resourceRecords = [];
107 34
        foreach ($zones as $domain => $types) {
108 34
            $domain = rtrim($domain, '.').'.';
109 34
            foreach ($types as $type => $data) {
110 34
                $data = (array) $data;
111 34
                $type = RecordTypeEnum::getTypeFromName($type);
112 34
                foreach ($data as $rdata) {
113 34
                    $resourceRecords[] = (new ResourceRecord())
114 34
                        ->setName($domain)
115 34
                        ->setType($type)
116 34
                        ->setClass($this->defaultClass)
117 34
                        ->setTtl($this->defaultTtl)
118 34
                        ->setRdata($rdata);
119
                }
120
            }
121
        }
122
123 34
        return $resourceRecords;
124
    }
125
}
126