Passed
Push — master ( 2d4f15...ed59ee )
by Christian
02:15
created

ResolverAbstract::mapResults()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 1
nop 2
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
namespace RemotelyLiving\PHPDNS\Resolvers;
3
4
use RemotelyLiving\PHPDNS\Entities\DNSRecord;
5
use RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
6
use RemotelyLiving\PHPDNS\Entities\DNSRecordType;
7
use RemotelyLiving\PHPDNS\Entities\Hostname;
8
use RemotelyLiving\PHPDNS\Exceptions\InvalidArgumentException;
9
use RemotelyLiving\PHPDNS\Mappers\MapperInterface;
10
use RemotelyLiving\PHPDNS\Observability\Events\DNSQueried;
11
use RemotelyLiving\PHPDNS\Observability\Events\DNSQueryFailed;
12
use RemotelyLiving\PHPDNS\Observability\Events\DNSQueryProfiled;
13
use RemotelyLiving\PHPDNS\Observability\Traits\Dispatcher;
14
use RemotelyLiving\PHPDNS\Observability\Traits\Logger;
15
use RemotelyLiving\PHPDNS\Observability\Traits\Profileable;
16
use RemotelyLiving\PHPDNS\Resolvers\Exceptions\QueryFailure;
17
use RemotelyLiving\PHPDNS\Resolvers\Interfaces\ObservableResolver;
18
19
abstract class ResolverAbstract implements ObservableResolver
20
{
21
    use Logger,
22
        Dispatcher,
23
        Profileable;
24
25
    private $name = null;
26
27
    public function getName(): string
28
    {
29
        if ($this->name === null) {
30
            $explodedClass = explode('\\', get_class($this));
31
            $this->name = (string) array_pop($explodedClass);
32
        }
33
34
        return $this->name;
35
    }
36
37
    public function getARecords(string $hostname): DNSRecordCollection
38
    {
39
        return $this->getRecords($hostname, DNSRecordType::createA());
40
    }
41
42
    public function getAAAARecords(string $hostname): DNSRecordCollection
43
    {
44
        return $this->getRecords($hostname, DNSRecordType::createAAAA());
45
    }
46
47
    public function getCNAMERecords(string $hostname): DNSRecordCollection
48
    {
49
        return $this->getRecords($hostname, DNSRecordType::createCNAME());
50
    }
51
52
    public function getTXTRecords(string $hostname): DNSRecordCollection
53
    {
54
        return $this->getRecords($hostname, DNSRecordType::createTXT());
55
    }
56
57
    public function getMXRecords(string $hostname): DNSRecordCollection
58
    {
59
        return $this->getRecords($hostname, DNSRecordType::createMX());
60
    }
61
62
    public function recordTypeExists(string $hostname, string $recordType): bool
63
    {
64
        return !$this->getRecords($hostname, $recordType)->isEmpty();
65
    }
66
67
    public function hasRecord(DNSRecord $record): bool
68
    {
69
        return $this->getRecords($record->getHostname(), $record->getType())
70
            ->has($record);
71
    }
72
73
    public function getRecords(string $hostname, string $recordType = null): DNSRecordCollection
74
    {
75
        $recordType = DNSRecordType::createFromString($recordType ?? 'ANY');
76
        $hostname = Hostname::createFromString($hostname);
77
78
        $profile = $this->createProfile("{$this->getName()}:{$hostname}:{$recordType}");
79
        $profile->startTransaction();
80
81
        try {
82
            $result = ($recordType->equals(DNSRecordType::createANY()))
83
                ? $this->doQuery($hostname, $recordType)
84
                : $this->doQuery($hostname, $recordType)->filteredByType($recordType);
85
        } catch (QueryFailure $e) {
86
            $dnsQueryFailureEvent = new DNSQueryFailed($this, $hostname, $recordType, $e);
87
            $this->dispatch($dnsQueryFailureEvent);
88
            $this->getLogger()->error(
89
                'DNS query failed',
90
                ['event' => json_encode($dnsQueryFailureEvent), 'exception' => $e]
91
            );
92
93
            throw $e;
94
        } finally {
95
            $profile->endTransaction();
96
            $profile->samplePeakMemoryUsage();
97
            $dnsQueryProfiledEvent = new DNSQueryProfiled($profile);
98
            $this->dispatch($dnsQueryProfiledEvent);
99
            $this->getLogger()->info('DNS query profiled', ['event' => json_encode($dnsQueryProfiledEvent)]);
100
        }
101
102
        $dnsQueriedEvent = new DNSQueried($this, $hostname, $recordType, $result);
103
        $this->dispatch($dnsQueriedEvent);
104
        $this->getLogger()->info('DNS queried', ['event' => json_encode($dnsQueriedEvent)]);
105
        return $result;
106
    }
107
108
    public function mapResults(MapperInterface $mapper, array $results) : DNSRecordCollection
109
    {
110
        $collection = new DNSRecordCollection();
111
        array_map(function (array $fields) use (&$collection, $mapper) {
112
            try {
113
                $collection[] = $mapper->mapFields($fields)->toDNSRecord();
114
            } catch (InvalidArgumentException $e) {
115
                $this->getLogger()->error('Invalid fields passed to mapper', $fields);
116
            }
117
        }, $results);
118
119
        return $collection;
120
    }
121
122
    abstract protected function doQuery(Hostname $hostname, DNSRecordType $recordType): DNSRecordCollection;
123
}
124