GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — develop (#322)
by
unknown
02:03
created

AbstractUri::parse()   F

Complexity

Conditions 13
Paths 2048

Size

Total Lines 37
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 17
nc 2048
nop 1
dl 0
loc 37
rs 2.7716
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Part of the Joomla Framework Uri Package
4
 *
5
 * @copyright  Copyright (C) 2005 - 2013 Open Source Matters. All rights reserved.
6
 * @license    GNU General Public License version 2 or later; see LICENSE
7
 */
8
9
namespace Joomla\Uri;
10
11
/**
12
 * Uri Class
13
 *
14
 * Abstract base for out uri classes.
15
 *
16
 * This class should be considered an implementation detail. Typehint against UriInterface.
17
 *
18
 * @since  1.0
19
 */
20
abstract class AbstractUri implements UriInterface
21
{
22
	/**
23
	 * @var    string  Original URI
24
	 * @since  1.0
25
	 */
26
	protected $uri = null;
27
28
	/**
29
	 * @var    string  Protocol
30
	 * @since  1.0
31
	 */
32
	protected $scheme = null;
33
34
	/**
35
	 * @var    string  Host
36
	 * @since  1.0
37
	 */
38
	protected $host = null;
39
40
	/**
41
	 * @var    integer  Port
42
	 * @since  1.0
43
	 */
44
	protected $port = null;
45
46
	/**
47
	 * @var    string  Username
48
	 * @since  1.0
49
	 */
50
	protected $user = null;
51
52
	/**
53
	 * @var    string  Password
54
	 * @since  1.0
55
	 */
56
	protected $pass = null;
57
58
	/**
59
	 * @var    string  Path
60
	 * @since  1.0
61
	 */
62
	protected $path = null;
63
64
	/**
65
	 * @var    string  Query
66
	 * @since  1.0
67
	 */
68
	protected $query = null;
69
70
	/**
71
	 * @var    string  Anchor
72
	 * @since  1.0
73
	 */
74
	protected $fragment = null;
75
76
	/**
77
	 * @var    array  Query variable hash
78
	 * @since  1.0
79
	 */
80
	protected $vars = array();
81
82
	/**
83
	 * Constructor.
84
	 * You can pass a URI string to the constructor to initialise a specific URI.
85
	 *
86
	 * @param   string  $uri  The optional URI string
87
	 *
88
	 * @since   1.0
89
	 */
90
	public function __construct($uri = null)
91
	{
92
		if (!is_null($uri))
93
		{
94
			$this->parse($uri);
95
		}
96
	}
97
98
	/**
99
	 * Magic method to get the string representation of the URI object.
100
	 *
101
	 * @return  string
102
	 *
103
	 * @since   1.0
104
	 */
105
	public function __toString()
106
	{
107
		return $this->toString();
108
	}
109
110
	/**
111
	 * Returns full uri string.
112
	 *
113
	 * @param   array  $parts  An array specifying the parts to render.
114
	 *
115
	 * @return  string  The rendered URI string.
116
	 *
117
	 * @since   1.0
118
	 */
119
	public function toString(array $parts = array('scheme', 'user', 'pass', 'host', 'port', 'path', 'query', 'fragment'))
120
	{
121
		// Make sure the query is created
122
		$query = $this->getQuery();
123
124
		$uri = '';
125
		$uri .= in_array('scheme', $parts) ? (!empty($this->scheme) ? $this->scheme . '://' : '') : '';
126
		$uri .= in_array('user', $parts) ? $this->user : '';
127
		$uri .= in_array('pass', $parts) ? (!empty($this->pass) ? ':' : '') . $this->pass . (!empty($this->user) ? '@' : '') : '';
128
		$uri .= in_array('host', $parts) ? $this->host : '';
129
		$uri .= in_array('port', $parts) ? (!empty($this->port) ? ':' : '') . $this->port : '';
130
		$uri .= in_array('path', $parts) ? $this->path : '';
131
		$uri .= in_array('query', $parts) ? (!empty($query) ? '?' . $query : '') : '';
132
		$uri .= in_array('fragment', $parts) ? (!empty($this->fragment) ? '#' . $this->fragment : '') : '';
133
134
		return $uri;
135
	}
136
137
	/**
138
	 * Checks if variable exists.
139
	 *
140
	 * @param   string  $name  Name of the query variable to check.
141
	 *
142
	 * @return  boolean  True if the variable exists.
143
	 *
144
	 * @since   1.0
145
	 */
146
	public function hasVar($name)
147
	{
148
		return array_key_exists($name, $this->vars);
149
	}
150
151
	/**
152
	 * Returns a query variable by name.
153
	 *
154
	 * @param   string  $name     Name of the query variable to get.
155
	 * @param   string  $default  Default value to return if the variable is not set.
156
	 *
157
	 * @return  array   Query variables.
158
	 *
159
	 * @since   1.0
160
	 */
161
	public function getVar($name, $default = null)
162
	{
163
		if (array_key_exists($name, $this->vars))
164
		{
165
			return $this->vars[$name];
166
		}
167
168
		return $default;
0 ignored issues
show
Bug Compatibility introduced by
The expression return $default; of type string|null is incompatible with the return type declared by the interface Joomla\Uri\UriInterface::getVar of type array as it can also be of type string which is not included in this return type.
Loading history...
169
	}
170
171
	/**
172
	 * Returns flat query string.
173
	 *
174
	 * @param   boolean  $toArray  True to return the query as a key => value pair array.
175
	 *
176
	 * @return  string   Query string.
177
	 *
178
	 * @since   1.0
179
	 */
180
	public function getQuery($toArray = false)
181
	{
182
		if ($toArray)
183
		{
184
			return $this->vars;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->vars; (array) is incompatible with the return type declared by the interface Joomla\Uri\UriInterface::getQuery of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
185
		}
186
187
		// If the query is empty build it first
188
		if (is_null($this->query))
189
		{
190
			$this->query = self::buildQuery($this->vars);
191
		}
192
193
		return $this->query;
194
	}
195
196
	/**
197
	 * Get URI scheme (protocol)
198
	 * ie. http, https, ftp, etc...
199
	 *
200
	 * @return  string  The URI scheme.
201
	 *
202
	 * @since   1.0
203
	 */
204
	public function getScheme()
205
	{
206
		return $this->scheme;
207
	}
208
209
	/**
210
	 * Get URI username
211
	 * Returns the username, or null if no username was specified.
212
	 *
213
	 * @return  string  The URI username.
214
	 *
215
	 * @since   1.0
216
	 */
217
	public function getUser()
218
	{
219
		return $this->user;
220
	}
221
222
	/**
223
	 * Get URI password
224
	 * Returns the password, or null if no password was specified.
225
	 *
226
	 * @return  string  The URI password.
227
	 *
228
	 * @since   1.0
229
	 */
230
	public function getPass()
231
	{
232
		return $this->pass;
233
	}
234
235
	/**
236
	 * Get URI host
237
	 * Returns the hostname/ip or null if no hostname/ip was specified.
238
	 *
239
	 * @return  string  The URI host.
240
	 *
241
	 * @since   1.0
242
	 */
243
	public function getHost()
244
	{
245
		return $this->host;
246
	}
247
248
	/**
249
	 * Get URI port
250
	 * Returns the port number, or null if no port was specified.
251
	 *
252
	 * @return  integer  The URI port number.
253
	 *
254
	 * @since   1.0
255
	 */
256
	public function getPort()
257
	{
258
		return (isset($this->port)) ? $this->port : null;
259
	}
260
261
	/**
262
	 * Gets the URI path string.
263
	 *
264
	 * @return  string  The URI path string.
265
	 *
266
	 * @since   1.0
267
	 */
268
	public function getPath()
269
	{
270
		return $this->path;
271
	}
272
273
	/**
274
	 * Get the URI archor string
275
	 * Everything after the "#".
276
	 *
277
	 * @return  string  The URI anchor string.
278
	 *
279
	 * @since   1.0
280
	 */
281
	public function getFragment()
282
	{
283
		return $this->fragment;
284
	}
285
286
	/**
287
	 * Checks whether the current URI is using HTTPS.
288
	 *
289
	 * @return  boolean  True if using SSL via HTTPS.
290
	 *
291
	 * @since   1.0
292
	 */
293
	public function isSSL()
294
	{
295
		return $this->getScheme() == 'https' ? true : false;
296
	}
297
298
	/**
299
	 * Build a query from a array (reverse of the PHP parse_str()).
300
	 *
301
	 * @param   array  $params  The array of key => value pairs to return as a query string.
302
	 *
303
	 * @return  string  The resulting query string.
304
	 *
305
	 * @see     parse_str()
306
	 * @since   1.0
307
	 */
308
	protected static function buildQuery(array $params)
309
	{
310
		return urldecode(http_build_query($params, '', '&'));
311
	}
312
313
	/**
314
	 * Parse a given URI and populate the class fields.
315
	 *
316
	 * @param   string  $uri  The URI string to parse.
317
	 *
318
	 * @return  boolean  True on success.
319
	 *
320
	 * @since   1.0
321
	 */
322
	protected function parse($uri)
323
	{
324
		// Set the original URI to fall back on
325
		$this->uri = $uri;
326
327
		/*
328
		 * Parse the URI and populate the object fields. If URI is parsed properly,
329
		 * set method return value to true.
330
		 */
331
332
		$parts = UriHelper::parse_url($uri);
333
334
		$retval = ($parts) ? true : false;
335
336
		// We need to replace &amp; with & for parse_str to work right...
337
		if (isset($parts['query']) && strpos($parts['query'], '&amp;'))
338
		{
339
			$parts['query'] = str_replace('&amp;', '&', $parts['query']);
340
		}
341
342
		$this->scheme   = isset($parts['scheme']) ? $parts['scheme'] : null;
343
		$this->user     = isset($parts['user']) ? $parts['user'] : null;
344
		$this->pass     = isset($parts['pass']) ? $parts['pass'] : null;
345
		$this->host     = isset($parts['host']) ? $parts['host'] : null;
346
		$this->port     = isset($parts['port']) ? $parts['port'] : null;
347
		$this->path     = isset($parts['path']) ? $parts['path'] : null;
348
		$this->query    = isset($parts['query']) ? $parts['query'] : null;
349
		$this->fragment = isset($parts['fragment']) ? $parts['fragment'] : null;
350
351
		// Parse the query
352
		if (isset($parts['query']))
353
		{
354
			parse_str($parts['query'], $this->vars);
355
		}
356
357
		return $retval;
358
	}
359
360
	/**
361
	 * Resolves //, ../ and ./ from a path and returns
362
	 * the result. Eg:
363
	 *
364
	 * /foo/bar/../boo.php	=> /foo/boo.php
365
	 * /foo/bar/../../boo.php => /boo.php
366
	 * /foo/bar/.././/boo.php => /foo/boo.php
367
	 *
368
	 * @param   string  $path  The URI path to clean.
369
	 *
370
	 * @return  string  Cleaned and resolved URI path.
371
	 *
372
	 * @since   1.0
373
	 */
374
	protected function cleanPath($path)
375
	{
376
		$path = explode('/', preg_replace('#(/+)#', '/', $path));
377
378
		for ($i = 0, $n = count($path); $i < $n; $i++)
379
		{
380
			if ($path[$i] == '.' || $path[$i] == '..')
381
			{
382
				if (($path[$i] == '.') || ($path[$i] == '..' && $i == 1 && $path[0] == ''))
383
				{
384
					unset($path[$i]);
385
					$path = array_values($path);
386
					$i--;
387
					$n--;
388
				}
389
				elseif ($path[$i] == '..' && ($i > 1 || ($i == 1 && $path[0] != '')))
390
				{
391
					unset($path[$i]);
392
					unset($path[$i - 1]);
393
					$path = array_values($path);
394
					$i -= 2;
395
					$n -= 2;
396
				}
397
			}
398
		}
399
400
		return implode('/', $path);
401
	}
402
}
403