Completed
Pull Request — master (#85)
by Peter
03:38 queued 02:25
created

Url::__toString()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 7
nc 9
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
    /** @var null|string */
23
    protected $toString;
24
25
    /**
26
     * @param string $url
27
     *
28
     * @return static
29
     */
30
    public static function create(string $url)
31
    {
32
        return new static($url);
33
    }
34
35
    public function __construct(string $url)
36
    {
37
        $urlProperties = parse_url($url);
38
39
        foreach (['scheme', 'host', 'path', 'port', 'query'] as $property) {
40
            if (isset($urlProperties[$property])) {
41
                $this->$property = $urlProperties[$property];
42
            }
43
        }
44
    }
45
46
    public function isRelative(): bool
47
    {
48
        return is_null($this->host);
49
    }
50
51
    public function isProtocolIndependent(): bool
52
    {
53
        return is_null($this->scheme);
54
    }
55
56
    public function hasCrawlableScheme(): bool
57
    {
58
        return in_array($this->scheme, [null, 'http', 'https']);
59
    }
60
61
    /**
62
     * @param string $scheme
63
     *
64
     * @return $this
65
     */
66
    public function setScheme(string $scheme)
67
    {
68
        $this->scheme = $scheme;
69
        $this->toString = null;
70
71
        return $this;
72
    }
73
74
    /**
75
     * @param string $host
76
     *
77
     * @return $this
78
     */
79
    public function setHost(string $host)
80
    {
81
        $this->host = $host;
82
        $this->toString = null;
83
84
        return $this;
85
    }
86
87
    /**
88
     * @param $port
89
     *
90
     * @return $this
91
     */
92
    public function setPort(int $port)
93
    {
94
        $this->port = $port;
95
        $this->toString = null;
96
97
        return $this;
98
    }
99
100
    /**
101
     * @return $this
102
     */
103
    public function removeFragment()
104
    {
105
        $this->path = explode('#', $this->path)[0];
106
        $this->toString = null;
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
        $this->toString = null;
120
121
        return $this;
122
    }
123
124
    /**
125
     * @return null|string
126
     */
127
    public function path()
128
    {
129
        return $this->path;
130
    }
131
132
    /**
133
     * @deprecated This function is not being used internally anymore and will be removed in the next major version.
134
     *
135
     * @return null|string
136
     */
137
    public function directory()
138
    {
139
        $segments = $this->segments();
0 ignored issues
show
Deprecated Code introduced by
The method Spatie\Crawler\Url::segments() has been deprecated with message: This function is not being used internally anymore and will be removed in the next major version.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
140
        array_pop($segments);
141
142
        return implode('/', $segments).'/';
143
    }
144
145
    /**
146
     * @deprecated This function is not being used internally anymore and will be removed in the next major version.
147
     *
148
     * @param int|null $index
149
     *
150
     * @return array|null|string
151
     */
152
    public function segments(int $index = null)
153
    {
154
        $segments = collect(explode('/', $this->path()))
155
            ->filter(function ($value) {
156
                return $value !== '';
157
            })
158
            ->values()
159
            ->toArray();
160
161
        if (! is_null($index)) {
162
            return $this->segment($index);
163
        }
164
165
        return $segments;
166
    }
167
168
    /**
169
     * @param int $index
170
     *
171
     * @return string|null
172
     */
173
    public function segment(int $index)
174
    {
175
        if (! isset($this->segments()[$index - 1])) {
0 ignored issues
show
Deprecated Code introduced by
The method Spatie\Crawler\Url::segments() has been deprecated with message: This function is not being used internally anymore and will be removed in the next major version.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
176
            return;
177
        }
178
179
        return $this->segments()[$index - 1];
0 ignored issues
show
Deprecated Code introduced by
The method Spatie\Crawler\Url::segments() has been deprecated with message: This function is not being used internally anymore and will be removed in the next major version.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
180
    }
181
182
    public function isEqual(Url $otherUrl): bool
183
    {
184
        return (string) $this === (string) $otherUrl;
185
    }
186
187
    /**
188
     * @return string
189
     */
190
    public function __toString()
191
    {
192
        if (!$this->toString) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->toString of type null|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
193
            $path = $this->startsWith($this->path, '/') ? substr($this->path, 1) : $this->path;
194
195
            $port = ($this->port === 80 ? '' : ":{$this->port}");
196
197
            $queryString = (is_null($this->query) ? '' : "?{$this->query}");
198
199
            $this->toString = "{$this->scheme}://{$this->host}{$port}/{$path}{$queryString}";
200
        }
201
202
        return $this->toString;
203
    }
204
205
    /**
206
     * @param string|null $haystack
207
     * @param string|array $needles
208
     *
209
     * @return bool
210
     */
211
    public function startsWith($haystack, $needles): bool
212
    {
213
        foreach ((array) $needles as $needle) {
214
            if ($needle != '' && substr($haystack, 0, strlen($needle)) === (string) $needle) {
215
                return true;
216
            }
217
        }
218
219
        return false;
220
    }
221
}
222