Completed
Pull Request — master (#55)
by Barry vd.
01:53
created

Url::isRelativeToPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
nop 0
1
<?php
2
3
namespace Spatie\Crawler;
4
5
class Url
6
{
7
    /** @var null|string */
8
    public $scheme;
9
10
    /** @var null|string */
11
    public $host;
12
13
    /** @var int */
14
    public $port = 80;
15
16
    /** @var null|string */
17
    public $path;
18
19
    /** @var null|string */
20
    public $query;
21
22
    /**
23
     * @param string $url
24
     *
25
     * @return static
26
     */
27
    public static function create(string $url)
28
    {
29
        return new static($url);
30
    }
31
32
    public function __construct(string $url)
33
    {
34
        $urlProperties = parse_url($url);
35
36
        foreach (['scheme', 'host', 'path', 'port', 'query'] as $property) {
37
            if (isset($urlProperties[$property])) {
38
                $this->$property = $urlProperties[$property];
39
            }
40
        }
41
    }
42
43
    public function isRelative(): bool
44
    {
45
        return is_null($this->host);
46
    }
47
48
    public function isProtocolIndependent(): bool
49
    {
50
        return is_null($this->scheme);
51
    }
52
53
    public function hasCrawlableScheme(): bool
54
    {
55
        return in_array($this->scheme, [null, 'http', 'https']);
56
    }
57
58
    /**
59
     * @param string $scheme
60
     *
61
     * @return $this
62
     */
63
    public function setScheme(string $scheme)
64
    {
65
        $this->scheme = $scheme;
66
67
        return $this;
68
    }
69
70
    /**
71
     * @param string $host
72
     *
73
     * @return $this
74
     */
75
    public function setHost(string $host)
76
    {
77
        $this->host = $host;
78
79
        return $this;
80
    }
81
82
    /**
83
     * @param $port
84
     *
85
     * @return $this
86
     */
87
    public function setPort(int $port)
88
    {
89
        $this->port = $port;
90
91
        return $this;
92
    }
93
94
    /**
95
     * @return $this
96
     */
97
    public function removeFragment()
98
    {
99
        $this->path = explode('#', $this->path)[0];
100
101
        return $this;
102
    }
103
104
    /**
105
     * @param $path
106
     *
107
     * @return $this
108
     */
109
    public function setPath(string $path)
110
    {
111
        $this->path = $path;
112
113
        return $this;
114
    }
115
116
    /**
117
     * @return null|string
118
     */
119
    public function path()
120
    {
121
        return $this->path;
122
    }
123
124
    /**
125
     * @return null|string
126
     */
127
    public function directory()
128
    {
129
        $segments = $this->segments();
130
        array_pop($segments);
131
132
        return implode('/', $segments).'/';
133
    }
134
135
    /**
136
     * @param int|null $index
137
     *
138
     * @return array|null|string
139
     */
140
    public function segments(int $index = null)
141
    {
142
        $segments = collect(explode('/', $this->path()))
143
            ->filter(function ($value) {
144
                return $value !== '';
145
            })
146
            ->values()
147
            ->toArray();
148
149
        if (! is_null($index)) {
150
            return $this->segment($index);
151
        }
152
153
        return $segments;
154
    }
155
156
    /**
157
     * @param int $index
158
     *
159
     * @return string|null
160
     */
161
    public function segment(int $index)
162
    {
163
        if (! isset($this->segments()[$index - 1])) {
164
            return;
165
        }
166
167
        return $this->segments()[$index - 1];
168
    }
169
170
    public function isEqual(Url $otherUrl): bool
171
    {
172
        return (string) $this === (string) $otherUrl;
173
    }
174
175
    /**
176
     * @return string
177
     */
178
    public function __toString()
179
    {
180
        $path = $this->startsWith($this->path, '/') ? substr($this->path, 1) : $this->path;
181
182
        $port = ($this->port === 80 ? '' : ":{$this->port}");
183
184
        $queryString = (is_null($this->query) ? '' : "?{$this->query}");
185
186
        return "{$this->scheme}://{$this->host}{$port}/{$path}{$queryString}";
187
    }
188
189
    /**
190
     * @param string|null $haystack
191
     * @param string|array $needles
192
     *
193
     * @return bool
194
     */
195
    public function startsWith($haystack, $needles): bool
196
    {
197
        foreach ((array) $needles as $needle) {
198
            if ($needle != '' && substr($haystack, 0, strlen($needle)) === (string) $needle) {
199
                return true;
200
            }
201
        }
202
203
        return false;
204
    }
205
}
206