Completed
Pull Request — master (#1)
by Philippe
04:41
created

Url::parse()   A

Complexity

Conditions 5
Paths 10

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 10
nop 1
dl 0
loc 20
ccs 10
cts 10
cp 1
crap 5
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
namespace Thinktomorrow\Url;
4
5
class Url
6
{
7
    /** @var ParsedUrl */
8
    private $parsedUrl;
9
10
    private $root;
11
12
    private $secure = false;
13
14 17
    private function __construct(ParsedUrl $parsedUrl)
15
    {
16 17
        $this->parsedUrl = $parsedUrl;
17 17
    }
18
19 18
    public static function fromString(string $url)
20
    {
21 18
        return new static( ParsedUrl::fromUrlString($url) );
22
    }
23
24 4
    public function setCustomRoot(Root $root)
25
    {
26 4
        $this->root = $root;
27
28 4
        return $this;
29
    }
30
31 4
    public function secure()
32
    {
33 4
        return $this->scheme(true);
34
    }
35
36 2
    public function nonSecure()
37
    {
38 2
        return $this->scheme(false);
39
    }
40
41 6
    private function scheme(bool $secure = true)
42
    {
43 6
        $this->parsedUrl = $this->parsedUrl->replaceScheme($secure ? 'https' : 'http');
44 6
        $this->secure = $secure;
45
46 6
        return $this;
47
    }
48
49 15
    public function get()
50
    {
51 15
        if ($this->root) {
52 4
            if ($this->secure) {
53 2
                $this->root->secure($this->secure);
54
            }
55
56
            // Path is reconstructed. Taken care of possible double slashes
57 4
            $path = str_replace('//', '/', '/'.trim($this->reassembleWithoutRoot(), '/'));
58
59 4
            return rtrim($this->root->get().$path,'/');
60
        }
61
62 11
        return $this->parsedUrl->get();
63
    }
64
65 1
    public function isAbsolute(): bool
66
    {
67 1
        return $this->parsedUrl->hasHost();
68
    }
69
70 9
    public function localize(string $localeSegment = null, array $available_locales = [])
71
    {
72 9
        $localizedPath = str_replace('//', '/',
73 9
            rtrim('/'.trim($localeSegment.$this->delocalizePath($available_locales), '/'), '/')
74
        );
75
76 9
        $this->parsedUrl = $this->parsedUrl->replacePath($localizedPath);
77
78 9
        return $this;
79
    }
80
81 9
    private function delocalizePath(array $available_locales)
82
    {
83 9
        if (!$this->parsedUrl->hasPath()) {
84 3
            return;
85
        }
86
87 9
        $path_segments = explode('/', trim($this->parsedUrl->path(), '/'));
88
89
        // Remove the locale segment if present
90 9
        if (in_array($path_segments[0], array_keys($available_locales))) {
91 1
            unset($path_segments[0]);
92
        }
93
94 9
        return '/'.implode('/', $path_segments);
95
    }
96
97 1
    public function __toString(): string
98
    {
99 1
        return $this->get();
100
    }
101
102
    /**
103
     * Construct a full url with the parsed url elements
104
     * resulted from a parse_url() function call.
105
     *
106
     * @return string
107
     */
108 4
    private function reassembleWithoutRoot()
109
    {
110
        /**
111
         * In some rare conditions the path is interpreted as the host when there is no domain.tld format given.
112
         * This is still considered a valid url, be it with only a tld as indication.
113
         */
114 4
        $path = ($this->parsedUrl->hasPath() && $this->parsedUrl->path() != $this->root->host())
115 4
                    ? $this->parsedUrl->path()
116 4
                    : '';
117
118
        return $path
119 4
            .($this->parsedUrl->hasQuery() ? '?'.$this->parsedUrl->query() : '')
120 4
            .($this->parsedUrl->hasHash() ? '#'.$this->parsedUrl->hash() : '');
121
    }
122
}
123