Completed
Push — master ( b5f45d...daaee0 )
by Christian
02:22
created

Cached   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 27
dl 0
loc 74
rs 10
c 0
b 0
f 0
wmc 8

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A extractAverageTTL() 0 15 3
A buildCacheKey() 0 3 1
A doQuery() 0 15 2
A flush() 0 3 1
1
<?php
2
namespace RemotelyLiving\PHPDNS\Resolvers;
3
4
use Psr\Cache\CacheItemPoolInterface;
5
use RemotelyLiving\PHPDNS\Entities\DNSRecordCollection;
6
use RemotelyLiving\PHPDNS\Entities\DNSRecordType;
7
use RemotelyLiving\PHPDNS\Entities\Hostname;
8
use RemotelyLiving\PHPDNS\Resolvers\Interfaces\Resolver;
9
10
class Cached extends ResolverAbstract
11
{
12
    protected const DEFAULT_CACHE_TTL = 300;
13
    private const CACHE_KEY_TEMPLATE = '%s:%s:%s';
14
15
    /**
16
     * @var \Psr\Cache\CacheItemPoolInterface
17
     */
18
    private $cache;
19
20
    /**
21
     * @var \RemotelyLiving\PHPDNS\Resolvers\Interfaces\Resolver
22
     */
23
    private $resolver;
24
25
    /**
26
     * @var string
27
     */
28
    private $namespace = 'php-dns';
29
30
    /**
31
     * @var int|null
32
     */
33
    private $ttlSeconds;
34
35
    public function __construct(CacheItemPoolInterface $cache, Resolver $resolver, int $ttlSeconds = null)
36
    {
37
        $this->cache = $cache;
38
        $this->resolver = $resolver;
39
        $this->ttlSeconds = $ttlSeconds;
40
    }
41
42
    public function flush(): void
43
    {
44
        $this->cache->clear();
45
    }
46
47
    protected function doQuery(Hostname $hostname, DNSRecordType $recordType): DNSRecordCollection
48
    {
49
        $cachedResult = $this->cache->getItem($this->buildCacheKey($hostname, $recordType));
50
51
        if ($cachedResult->isHit()) {
52
            return $cachedResult->get();
53
        }
54
55
        $dnsRecords = $this->resolver->getRecords($hostname, $recordType);
56
        $ttlSeconds = $this->ttlSeconds ?? $this->extractAverageTTL($dnsRecords);
57
        $cachedResult->expiresAfter($ttlSeconds);
58
        $cachedResult->set($dnsRecords);
59
        $this->cache->save($cachedResult);
60
61
        return $dnsRecords;
62
    }
63
64
    private function buildCacheKey(Hostname $hostname, DNSRecordType $recordType): string
65
    {
66
        return md5(sprintf(self::CACHE_KEY_TEMPLATE, $this->namespace, (string) $hostname, (string) $recordType));
67
    }
68
69
    private function extractAverageTTL(DNSRecordCollection $recordCollection): int
70
    {
71
        $ttls = [];
72
73
        if ($recordCollection->isEmpty()) {
74
            return self::DEFAULT_CACHE_TTL;
75
        }
76
77
        /** @var \RemotelyLiving\PHPDNS\Entities\DNSRecord $record */
78
        foreach ($recordCollection as $record) {
79
            /** @scrutinizer ignore-call */
80
            $ttls[] = $record->getTTL();
81
        }
82
83
        return (int) array_sum($ttls) / $recordCollection->count();
84
    }
85
}
86