Completed
Push — master ( 36a9d2...1b21eb )
by Freek
02:00
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 isRelativeToPath(): bool
49
    {
50
        $doesntStartWithForwardSlash = substr($this->path(), 0, 1) != '/';
51
52
        return $this->isRelative() && $doesntStartWithForwardSlash;
53
    }
54
55
    public function isProtocolIndependent(): bool
56
    {
57
        return is_null($this->scheme);
58
    }
59
60
    public function hasCrawlableScheme(): bool
61
    {
62
        return in_array($this->scheme, [null, 'http', 'https']);
63
    }
64
65
    /**
66
     * @param string $scheme
67
     *
68
     * @return $this
69
     */
70
    public function setScheme(string $scheme)
71
    {
72
        $this->scheme = $scheme;
73
74
        return $this;
75
    }
76
77
    /**
78
     * @param string $host
79
     *
80
     * @return $this
81
     */
82
    public function setHost(string $host)
83
    {
84
        $this->host = $host;
85
86
        return $this;
87
    }
88
89
    /**
90
     * @param $port
91
     *
92
     * @return $this
93
     */
94
    public function setPort(int $port)
95
    {
96
        $this->port = $port;
97
98
        return $this;
99
    }
100
101
    /**
102
     * @return $this
103
     */
104
    public function removeFragment()
105
    {
106
        $this->path = explode('#', $this->path)[0];
107
108
        return $this;
109
    }
110
111
    /**
112
     * @param $path
113
     *
114
     * @return $this
115
     */
116
    public function setPath(string $path)
117
    {
118
        $this->path = $path;
119
120
        return $this;
121
    }
122
123
    /**
124
     * @return null|string
125
     */
126
    public function path()
127
    {
128
        return $this->path;
129
    }
130
131
    /**
132
     * @return null|string
133
     */
134
    public function directory()
135
    {
136
        $segments = $this->segments();
137
        array_pop($segments);
138
139
        return implode('/', $segments).'/';
140
    }
141
142
    /**
143
     * @param int|null $index
144
     *
145
     * @return array|null|string
146
     */
147
    public function segments(int $index = null)
148
    {
149
        $segments = collect(explode('/', $this->path()))
150
            ->filter(function ($value) {
151
                return $value !== '';
152
            })
153
            ->values()
154
            ->toArray();
155
156
        if (! is_null($index)) {
157
            return $this->segment($index);
158
        }
159
160
        return $segments;
161
    }
162
163
    /**
164
     * @param int $index
165
     *
166
     * @return string|null
167
     */
168
    public function segment(int $index)
169
    {
170
        if (! isset($this->segments()[$index - 1])) {
171
            return;
172
        }
173
174
        return $this->segments()[$index - 1];
175
    }
176
177
    public function isEqual(Url $otherUrl): bool
178
    {
179
        return (string) $this === (string) $otherUrl;
180
    }
181
182
    /**
183
     * @return string
184
     */
185
    public function __toString()
186
    {
187
        $path = $this->startsWith($this->path, '/') ? substr($this->path, 1) : $this->path;
188
189
        $port = ($this->port === 80 ? '' : ":{$this->port}");
190
191
        $queryString = (is_null($this->query) ? '' : "?{$this->query}");
192
193
        return "{$this->scheme}://{$this->host}{$port}/{$path}{$queryString}";
194
    }
195
196
    /**
197
     * @param string|null $haystack
198
     * @param string|array $needles
199
     *
200
     * @return bool
201
     */
202
    public function startsWith($haystack, $needles): bool
203
    {
204
        foreach ((array) $needles as $needle) {
205
            if ($needle != '' && substr($haystack, 0, strlen($needle)) === (string) $needle) {
206
                return true;
207
            }
208
        }
209
210
        return false;
211
    }
212
}
213