Failed Conditions
Pull Request — master (#63)
by Jonathan
08:16 queued 05:30
created

Parser   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Test Coverage

Coverage 95.65%

Importance

Changes 0
Metric Value
dl 0
loc 81
ccs 22
cts 23
cp 0.9565
rs 10
c 0
b 0
f 0
wmc 9

3 Methods

Rating   Name   Duplication   Size   Complexity  
B parseUrl() 0 26 5
A __construct() 0 3 1
A doParseUrl() 0 18 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Purl;
6
7
use Pdp\Parser as PslParser;
8
use function array_merge;
9
use function array_reverse;
10
use function explode;
11
use function implode;
12
use function parse_url;
13
use function preg_match;
14
use function sprintf;
15
16
/**
17
 * Parser class.
18
 */
19
class Parser implements ParserInterface
20
{
21
    /** @var PslParser Public Suffix List parser */
22
    private $pslParser;
23
24
    /** @var mixed[] */
25
    private static $defaultParts = [
26
        'scheme'             => null,
27
        'host'               => null,
28
        'port'               => null,
29
        'user'               => null,
30
        'pass'               => null,
31
        'path'               => null,
32
        'query'              => null,
33
        'fragment'           => null,
34
        'publicSuffix'       => null,
35
        'registerableDomain' => null,
36
        'subdomain'          => null,
37
        'canonical'          => null,
38
        'resource'           => null,
39
    ];
40
41 59
    public function __construct(PslParser $pslParser)
42
    {
43 59
        $this->pslParser = $pslParser;
44 59
    }
45
46
    /**
47
     * @param Url|string $url
48
     *
49
     * @return mixed[]
50
     */
51 59
    public function parseUrl($url) : array
52
    {
53 59
        $url = (string) $url;
54
55 59
        $parsedUrl = $this->doParseUrl($url);
56
57 58
        if ($parsedUrl === []) {
58
            throw new \InvalidArgumentException(sprintf('Invalid url %s', $url));
59
        }
60
61 58
        $parsedUrl = array_merge(self::$defaultParts, $parsedUrl);
62
63 58
        if (isset($parsedUrl['host'])) {
64 57
            $parsedUrl['publicSuffix']       = $this->pslParser->getPublicSuffix($parsedUrl['host']);
65 57
            $parsedUrl['registerableDomain'] = $this->pslParser->getRegisterableDomain($parsedUrl['host']);
66 57
            $parsedUrl['subdomain']          = $this->pslParser->getSubdomain($parsedUrl['host']);
67 57
            $parsedUrl['canonical']          = implode('.', array_reverse(explode('.', $parsedUrl['host']))) . ($parsedUrl['path'] ?? '') . (isset($parsedUrl['query']) ? '?' . $parsedUrl['query'] : '');
68
69 57
            $parsedUrl['resource'] = $parsedUrl['path'] ?? '';
70
71 57
            if (isset($parsedUrl['query'])) {
72 5
                $parsedUrl['resource'] .= '?' . $parsedUrl['query'];
73
            }
74
        }
75
76 58
        return $parsedUrl;
77
    }
78
79
    /**
80
     * @return mixed[]
81
     */
82 59
    protected function doParseUrl(string $url) : array
83
    {
84
        // If there's a single leading forward slash, use parse_url()
85
        // Expected matches:
86
        //
87
        // "/one/two"   YES
88
        // "/"          YES PLEASE
89
        // "//"         NO
90
        // "//one/two"  NO
91
        // ""           HELL NO
92 59
        if (preg_match('#^[\/]([^\/]|$)#', $url) === 1) {
93 2
            $parsedUrl = parse_url($url);
94
95 2
            return $parsedUrl !== false ? $parsedUrl : [];
96
        }
97
98
        // Otherwise use the PSL parser
99 58
        return $this->pslParser->parseUrl($url)->toArray();
100
    }
101
}
102