Passed
Push — master ( d0466a...c02546 )
by Zlatin
01:22
created

Uri::withScheme()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0185

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 10
ccs 5
cts 6
cp 0.8333
crap 2.0185
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace DevOp\Core\Http;
3
4
use Psr\Http\Message\UriInterface;
5
6
class Uri implements UriInterface
7
{
8
9
    /**
10
     * @var array
11
     */
12
    private static $schemes = array(
13
        'http' => 80,
14
        'https' => 443
15
    );
16
17
    /**
18
     * @var string|null
19
     */
20
    private $fragment;
21
22
    /**
23
     * @var string|null
24
     */
25
    private $host;
26
27
    /**
28
     * @var string|null
29
     */
30
    private $path;
31
32
    /**
33
     * @var string|null
34
     */
35
    private $port;
36
37
    /**
38
     * @var string|null
39
     */
40
    private $query;
41
42
    /**
43
     * @var string|null
44
     */
45
    private $scheme;
46
47
    /**
48
     * @var string|null
49
     */
50
    private $userInfo;
51
52
    /**
53
     * @return \DevOp\Core\Http\Uri
54
     */
55 6
    public static function createFromGlobals()
56
    {
57
        
58 6
        $uri = new Uri();
59
        
60 6
        $scheme = 'http';
61 6
        if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') {
62
            $scheme .= 's';
63
        }
64
        
65 6
        $uri->withScheme($scheme);
66
        
67 6
        if (isset($_SERVER['REMOTE_PORT']) && (!isset(self::$schemes['http']) && !isset(self::$schemes['https']))) {
68
            $uri->withPort($_SERVER['REMOTE_PORT']);
69
        }
70
        
71 6
        if (isset($_SERVER['SERVER_NAME'])) {
72
            $host = $_SERVER['SERVER_NAME'];
73 6
        } else if (isset($_SERVER['SERVER_ADDR'])) {
74
            $host = $_SERVER['SERVER_ADDR'];
75
        } else {
76 6
            $host = '127.0.0.1';
77
        }
78
        
79 6
        $uri->withHost($host);
80
        
81 6
        if (isset($_SERVER['QUERY_STRING'])) {
82
            $uri->withQuery(ltrim($_SERVER['QUERY_STRING'], '?'));
83
        }
84
        
85 6
        return $uri;
86
    }
87
    
88
    /**
89
     * @return string
90
     */
91
    public function __toString()
92
    {
93
        $uri = $this->scheme;
94
        
95
        if ($this->userInfo !== null) {
96
            $uri .= "//{$this->userInfo}";
97
        }
98
        
99
        if ($this->port && !in_array($this->port, [self::$schemes['http'], self::$schemes['https']])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->port of type null|string is loosely compared to true; 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...
100
            $uri .= ":{$this->port}";
101
        }
102
        
103
        $uri .= $this->path;
104
        
105
        if ($this->query) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->query of type null|string is loosely compared to true; 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...
106
            $uri .= "?{$this->query}";
107
        }
108
        
109
        if ($this->fragment) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->fragment of type null|string is loosely compared to true; 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...
110
            $uri .= "#{$this->fragment}";
111
        }
112
        
113
        return $uri;
114
    }
115
116
    public function getAuthority()
117
    {
118
        return ($this->userInfo ?: $this->userInfo) . $this->host . ($this->port ?: ":{$this->port}");
119
    }
120
121 2
    public function getFragment()
122
    {
123 2
        return $this->fragment;
124
    }
125
126
    public function getHost()
127
    {
128
        return $this->host;
129
    }
130
131
    public function getPath()
132
    {
133
        return $this->path;
134
    }
135
136
    public function getPort()
137
    {
138
        return $this->port;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->port also could return the type string which is incompatible with the return type mandated by Psr\Http\Message\UriInterface::getPort() of null|integer.
Loading history...
139
    }
140
141
    public function getQuery()
142
    {
143
        return $this->query;
144
    }
145
146
    public function getScheme()
147
    {
148
        return $this->scheme;
149
    }
150
151
    public function getUserInfo()
152
    {
153
        return $this->userInfo;
154
    }
155
156
    /**
157
     * @param string $fragment
158
     * @return \DevOp\Core\Http\Uri|$this
159
     */
160 2
    public function withFragment($fragment)
161
    {
162 2
        if ($fragment === $this->fragment) {
163
            return $this;
164
        }
165
166 2
        $clone = clone $this;
167 2
        $clone->fragment = $fragment;
168
169 2
        return $clone;
170
    }
171
172
    /**
173
     * @param string $host
174
     * @return \DevOp\Core\Http\Uri|$this
175
     */
176 6
    public function withHost($host)
177
    {
178 6
        if ($host === $this->host) {
179
            return $this;
180
        }
181
182 6
        $clone = clone $this;
183 6
        $clone->host = $host;
184
185 6
        return $clone;
186
    }
187
188
    /**
189
     * @param string $path
190
     * @return \DevOp\Core\Http\Uri|$this
191
     */
192
    public function withPath($path)
193
    {
194
        if ($path === $this->path) {
195
            return $this;
196
        }
197
198
        $clone = clone $this;
199
        $clone->path = $path;
200
201
        return $clone;
202
    }
203
204
    /**
205
     * @param int $port
206
     * @return \DevOp\Core\Http\Uri|$this
207
     */
208
    public function withPort($port)
209
    {
210
        if ($port === $this->port) {
0 ignored issues
show
introduced by
The condition $port === $this->port can never be true.
Loading history...
211
            return $this;
212
        }
213
214
        $clone = clone $this;
215
        $clone->port = $port;
216
217
        return $clone;
218
    }
219
220
    /**
221
     * @param string  $query
222
     * @return \DevOp\Core\Http\Uri|$this
223
     */
224
    public function withQuery($query)
225
    {
226
        if ($query === $this->query) {
227
            return $this;
228
        }
229
230
        $clone = clone $this;
231
        $clone->query = $query;
232
233
        return $clone;
234
    }
235
236
    /**
237
     * @param string $scheme
238
     * @return \DevOp\Core\Http\Uri|$this
239
     */
240 6
    public function withScheme($scheme)
241
    {
242 6
        if ($scheme === $this->scheme) {
243
            return $this;
244
        }
245
246 6
        $clone = clone $this;
247 6
        $clone->scheme = $scheme;
248
249 6
        return $clone;
250
    }
251
252
    /**
253
     * @param string $user
254
     * @param string|null $password
255
     * @return \DevOp\Core\Http\Uri|$this
256
     */
257
    public function withUserInfo($user, $password = null)
258
    {
259
        $userInfo = $user;
260
        if (null !== $password) {
261
            $userInfo .= ":{$password}";
262
        }
263
264
        if ($userInfo === $this->userInfo) {
265
            return $this;
266
        }
267
268
        $clone = clone $this;
269
        $clone->userInfo = $userInfo;
270
271
        return $clone;
272
    }
273
}
274