Completed
Push — master ( 7532bb...b4d67d )
by Philippe
03:22
created

Root::parse()   A

Complexity

Conditions 6
Paths 14

Size

Total Lines 23
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 11
nc 14
nop 1
dl 0
loc 23
ccs 12
cts 12
cp 1
crap 6
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
namespace Thinktomorrow\Url;
4
5
use Thinktomorrow\Url\Exceptions\InvalidUrl;
6
7
class Root
8
{
9
    private $valid = false;
10
11
    private $scheme;
12
    private $schemeless = false;
13
    private $defaultScheme = 'http';
14
    private $secure = false;
15
16
    private $host;
17
    private $port;
18
19 10
    private function __construct(string $host)
20
    {
21 10
        $this->parse($host);
22
23 9
        if (false !== filter_var($this->get(), FILTER_VALIDATE_URL)) {
24 9
            $this->valid = true;
25
        }
26 9
    }
27
28 10
    public static function fromString(string $host)
29
    {
30 10
        return new self($host);
31
    }
32
33 9
    public function get()
34
    {
35 9
        $scheme = (!is_null($this->scheme)) ? $this->scheme.'://' : ($this->schemeless ? '//' : $this->defaultScheme.'://');
36 9
        $port = (!is_null($this->port)) ? ':'.$this->port : null;
37
38 9
        return $scheme.$this->host.$port;
39
    }
40
41 1
    public function valid(): bool
42
    {
43 1
        return $this->valid;
44
    }
45
46 7
    public function secure(): self
47
    {
48 7
        $this->secure = true;
49 7
        $this->scheme = 'https';
50
51 7
        return $this;
52
    }
53
54 3
    public function host(): string
55
    {
56 3
        return $this->host;
57
    }
58
59 1
    public function scheme(): ?string
60
    {
61 1
        return $this->scheme;
62
    }
63
64 10
    private function parse(string $host)
65
    {
66
        // Sanitize url input a bit to remove double slashes, but do not remove first slashes
67 10
        if ($host == '//') {
68 1
            $host = '/';
69
        }
70
71 10
        $parsed = parse_url($host);
72 10
        if (false === $parsed) {
73 1
            throw new InvalidUrl('Failed to parse url. Invalid url ['.$host.'] passed as parameter.');
74
        }
75
76
        // If a schemeless url is passed, parse_url will ignore this and strip the first tags
77
        // so we keep a reminder to explicitly reassemble the 'anonymous scheme' manually
78 9
        $this->schemeless = !isset($parsed['scheme']) && (0 === strpos($host, '//') && isset($parsed['host']));
79
80 9
        $this->scheme = $parsed['scheme'] ?? null;
81 9
        if ($this->scheme == 'https') {
82 7
            $this->secure();
83
        }
84
85 9
        $this->host = $this->parseHost($parsed);
86 9
        $this->port = $parsed['port'] ?? null;
87 9
    }
88
89 1
    public function __toString(): string
90
    {
91 1
        return $this->get();
92
    }
93
94 9
    private function parseHost(array $parsed): string
95
    {
96 9
        if (isset($parsed['host'])) {
97 7
            return $parsed['host'];
98
        }
99
100 6
        return (0 < strpos($parsed['path'], '/'))
101 1
                    ? substr($parsed['path'], 0, strpos($parsed['path'], '/'))
102 6
                    : $parsed['path'];
103
    }
104
}
105