Completed
Push — master ( 310e20...8220db )
by BENOIT
04:00
created

PublicSuffixProvider::fetchSuffixes()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 34
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 34
rs 8.439
c 0
b 0
f 0
cc 5
eloc 18
nc 2
nop 1
1
<?php
2
3
namespace BenTools\HostnameExtractor\SuffixProvider;
4
5
use CallbackFilterIterator;
6
use GuzzleHttp\Client;
7
8
class PublicSuffixProvider implements SuffixProviderInterface
9
{
10
    /**
11
     * @var Client
12
     */
13
    private $client;
14
15
    /**
16
     * @var string
17
     */
18
    private $listUrl;
19
20
    /**
21
     * @var array
22
     */
23
    private $cache;
24
25
    /**
26
     * @inheritDoc
27
     */
28
    public function __construct(
29
        Client $client,
30
        string $listUrl = 'https://publicsuffix.org/list/public_suffix_list.dat'
31
    ) {
32
    
33
        $this->client = $client;
34
        $this->listUrl = $listUrl;
35
    }
36
37
    /**
38
     * @param bool $force
39
     */
40
    public function fetchSuffixes(bool $force = false): void
41
    {
42
        if (null === $this->cache || true === $force) {
43
            $content = $this->client->get($this->listUrl)->getBody();
44
            // Create an iterator for the document
45
            $iterator = (function (string $content) {
46
                $tok = strtok($content, "\r\n");
47
                while (false !== $tok) {
48
                    $line = $tok;
49
                    $tok = strtok("\r\n");
50
51
                    // Remove "*." prefixes
52
                    if (0 === strpos($line, '*.')) {
53
                        $line = substr($line, 2, mb_strlen($line) - 2);
54
                    }
55
56
                    yield $line;
57
                }
58
            })($content);
59
60
            // Ignore commented lines
61
            $valid = function (string $string) {
62
                return 0 !== strpos($string, '//');
63
            };
64
            $suffixes = iterator_to_array(new CallbackFilterIterator($iterator, $valid));
65
66
            // Sort by suffix length
67
            usort($suffixes, function ($a, $b) {
68
                return mb_strlen($b) <=> mb_strlen($a);
69
            });
70
71
            $this->cache = $suffixes;
72
        }
73
    }
74
75
    /**
76
     * @inheritDoc
77
     */
78
    public function getSuffixes(): iterable
79
    {
80
        $this->fetchSuffixes();
81
        yield from $this->cache ?? new \EmptyIterator();
82
    }
83
}
84