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.
Passed
Push — master ( b1adde...186741 )
by Marius
11:19
created

UrlParserA::normalizePath()   B

Complexity

Conditions 11
Paths 73

Size

Total Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 11

Importance

Changes 0
Metric Value
cc 11
nc 73
nop 1
dl 0
loc 41
ccs 28
cts 28
cp 1
crap 11
rs 7.3166
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
namespace vsc\infrastructure\urls;
3
4
use vsc\infrastructure\BaseObject;
5
use vsc\presentation\requests\HttpRequestA;
6
7
class UrlParserA extends BaseObject implements UrlParserInterface {
8
	static protected $queryEncodingType = PHP_QUERY_RFC1738;
9
10
	private $sUrl;
11
	/**
12
	 * @var Url
13
	 */
14
	private $oUrl;
15
16
	/**
17
	 * @param string $sUrl
0 ignored issues
show
Documentation introduced by
Should the type for parameter $sUrl not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
18
	 */
19
	public function __construct($sUrl = null) {
20
		$this->setUrl($sUrl);
21
	}
22
23
	/**
24
	 * @return string
25
	 */
26
	public function __toString() {
27
		return $this->getCompleteUri();
28
	}
29
30
	/**
31
	 * This is somewhat ugly.
32
	 *  Returns an instance of the class on which the method is called
33
	 * @return Url
34
	 */
35
	public static function getCurrentUrl() {
36
		return static::parse_url(static::getRequestUri());
37
	}
38
39
	/**
40
	 * @return string
41
	 */
42 4
	public static function getRequestUri() {
43 4
		if (is_array($_SERVER) && array_key_exists('REQUEST_URI', $_SERVER)) {
44 3
			if (array_key_exists('HTTP_HOST', $_SERVER)) {
45 2
				$uri = 'http' . (HttpRequestA::isSecure() ? 's' : '') . '://' . $_SERVER['HTTP_HOST'];
46
			} else {
47 1
				$uri = '';
48
			}
49 3
			$uri .= $_SERVER['REQUEST_URI'];
50
		} else {
51 1
			$uri = '';
52
		}
53 4
		return $uri;
54
	}
55
56
	/**
57
	 * @param string $sUrl
58
	 * @return bool
59
	 */
60 1
	public static function urlHasScheme($sUrl) {
61 1
		$firstPos = min(strpos($sUrl, ':'), strpos($sUrl, '/'));
62 1
		$sScheme = substr($sUrl, 0, $firstPos);
63 1
		return Url::isValidScheme($sScheme);
64
	}
65
66
	/**
67
	 * @param Url $oUrl
68
	 * @param array $aParsed
69
	 * @return Url
70
	 */
71 1
	private static function loadParsedUrl($oUrl, $aParsed) {
72 1
		if (isset($aParsed['scheme'])) {
73 1
			$oUrl->setScheme($aParsed['scheme']);
74
		}
75 1
		if (isset($aParsed['host'])) {
76 1
			$oUrl->setHost($aParsed['host']);
77
		}
78 1
		if (isset($aParsed['port'])) {
79 1
			$oUrl->setPort($aParsed['port']);
80
		}
81 1
		if (isset($aParsed['path'])) {
82
			$oUrl->setPath($aParsed['path']);
83
		}
84 1
		if (isset($aParsed['query'])) {
85
			$oUrl->setRawQuery($aParsed['query']);
86
		}
87 1
		if (isset($aParsed['fragment'])) {
88
			$oUrl->setFragment($aParsed['fragment']);
89
		}
90 1
		return $oUrl;
91
	}
92
93
	/**
94
	 * This exists as the php::parse_url function sometimes breaks inexplicably
95
	 * @param string $sUrl
0 ignored issues
show
Documentation introduced by
Should the type for parameter $sUrl not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
96
	 * @return Url
97
	 */
98 25
	protected static function parse_url($sUrl = null) {
99 25
		if (is_null($sUrl)) {
100 1
			return new Url();
101
		}
102 24
		if (!stristr($sUrl, '://') && (substr($sUrl, 0, 2) != '//')) {
103 19
			$oUrl = new Url();
104 19
			$oUrl->setScheme('file');
105 19
			$oUrl->setPath($sUrl);
106 19
			return $oUrl;
107
		}
108
109
		try {
110 5
			if (!self::urlHasScheme($sUrl)) {
111 2
				$sUrl = (HttpRequestA::isSecure() ? 'https:' : 'http:') . $sUrl;
112
			}
113
114 5
			if (mb_detect_encoding($sUrl) !== 'ASCII') {
115
				$sUrl = rawurlencode($sUrl);
116
			}
117 5
			$aParsed = parse_url($sUrl);
118 5
			return self::loadParsedUrl(new Url(), $aParsed);
0 ignored issues
show
Security Bug introduced by
It seems like $aParsed defined by parse_url($sUrl) on line 117 can also be of type false; however, vsc\infrastructure\urls\...arserA::loadParsedUrl() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
119
		} catch (\Exception $e) {
120
			// failed php::parse_url
121
			return new Url();
122
		}
123
	}
124
125
	/**
126
	 * @param string $sUrl
127
	 */
128
	public function setUrl($sUrl) {
129
		$this->sUrl = $sUrl;
130
		$this->oUrl = static::parse_url($sUrl);
131
	}
132
133
	private function getSubdomainOf($sRootDomain) {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
134
		$sHost = strtolower($this->oUrl->getHost());
135
		$sSubDomains = stristr($sHost, '.' . $sRootDomain, true);
136
137
		return self::getTldOf($sSubDomains);
138
	}
139
140 1
	public static function getTldOf($sHost) {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
141 1
		if (ip2long($sHost) > 0 || empty($sHost)) { return false; }
142
143 1
		if (!strrpos($sHost, '.')) {
144 1
			return $sHost;
145
		} else {
146 1
			return substr($sHost, strrpos($sHost, '.') + 1);
147
		}
148
	}
149
150
	public static function getCurrentHostName() {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
151
		return $_SERVER['HTTP_HOST'];
152
	}
153
154 3
	public function getParentPath($iSteps = 0) {
155 3
		$sPath = self::normalizePath($this->oUrl->getPath());
156
157
158 3
		$len = strlen($sPath);
159 3
		$bHasPrefixSlash = (($len > 0) && ($sPath[0] == '/'));
160 3
		$bHasSuffixSlash = (($len > 1) && ($sPath[$len - 1] == '/'));
161
162
		// removing the folders from the path if there are parent references (../)
163 3
		$sPath = trim($sPath, '/');
164 3
		$aPath = explode('/', $sPath);
165
166 3
		if ($iSteps > 0) {
167
			// removing last $iSteps components of the path
168 3
			$aPath = array_slice($aPath, 0, -$iSteps);
169
		}
170
171
		// in case of actually getting the parent, we need to append the ending /
172
		// as we don't have a file as the last element in the path - same case for paths without a good termination
173 3
		$sPath = ($bHasPrefixSlash ? '/' : '') . implode('/', $aPath) . ($bHasSuffixSlash ? '/' : '');
174 3
		return $sPath;
175
	}
176
177 4
	public function setPath($sPath) {
178 4
		$this->oUrl->setPath($sPath);
179 4
	}
180
181 1
	public function getPath() {
182 1
		return $this->getParentPath(0);
183
	}
184
185
	/**
186
	 * @param string $sPath
187
	 * @return bool
188
	 */
189 1
	public static function isAbsolutePath($sPath) {
190 1
		return substr($sPath, 0, 1) == '/';
191
	}
192
193
	/**
194
	 * @return Url
0 ignored issues
show
Documentation introduced by
Should the return type not be string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
195
	 */
196 1
	static public function getSiteUri() {
197 1
		return static::url(static::getRequestUri())->getHost();
198
	}
199
200
	/**
201
	 * @param int $iSteps
202
	 * @return string
203
	 * @internal param bool $bFull
204
	 */
205 3
	public function getCompleteParentUri($iSteps = 1) {
206 3
		$sUrl = $this->oUrl->getScheme() .
207 3
			$this->oUrl->getHost() .
208 3
			$this->getParentPath($iSteps) .
209 3
			$this->oUrl->getRawQueryString() .
210 3
			$this->oUrl->getFragment();
211
212 3
		return $sUrl;
213
	}
214
215
	/**
216
	 * @return string
217
	 * @internal param bool $bFull
218
	 */
219 3
	public function getCompleteUri() {
220 3
		return $this->getCompleteParentUri(0);
221
	}
222
223
	/**
224
	 * @param string $sUri
225
	 * @param string $sTermination
226
	 * @return bool
227
	 */
228 26
	public static function hasGoodTermination($sUri, $sTermination = '/') {
229
		// last element should be an / or in the last part after / there should be a .
230 26
		return (substr($sUri, -1) == $sTermination || stristr(substr($sUri, strrpos($sUri, $sTermination)), '.'));
231
	}
232
233
	/**
234
	 * @param string $sUrl
235
	 * @return Url
236
	 */
237 18
	static public function url($sUrl) {
238 18
		return static::parse_url($sUrl);
239
	}
240
241
	/**
242
	 * @param string $sPath
243
	 * @return string
244
	 */
245 42
	static public function normalizePath($sPath) {
246 42
		if (empty ($sPath)) {
247 1
			return '';
248
		}
249
250 41
		$len = strlen($sPath);
251 41
		$bHasPrefixSlash = ($sPath[0] == '/');
252 41
		$bHasSuffixSlash = (($len > 1) && ($sPath[$len - 1] == '/'));
253
		// removing the folders from the path if there are parent references (../)
254 41
		$sPath = trim($sPath, '/');
255 41
		$aPath = explode('/', $sPath);
256
257 41
		$iCnt = 0;
258 41
		foreach ($aPath as $iKey => $sFolder) {
259 41
			switch ($sFolder) {
260 41
				case '..':
261 12
					$iCnt++;
262
263 12
					unset ($aPath[$iKey]);
264 12
					if (array_key_exists($iKey - 1, $aPath)) {
265 9
						$iPrevKey = $iKey - 1;
266
					} else {
267 3
						$sPrev = prev($aPath);
268 3
						$iPrevKey = array_search($sPrev, $aPath);
269
					}
270 12
					unset ($aPath[$iPrevKey]);
271 12
					break;
272 38
				case '.':
273 37
				case '':
274 16
					unset ($aPath[$iKey]);
275 41
					break;
276
			}
277
		}
278
279 41
		$sPath = ($bHasPrefixSlash ? '/' : '');
280 41
		if (count($aPath) > 0) {
281 30
			$sPath .= implode('/', $aPath) . ($bHasSuffixSlash ? '/' : '');
282
		}
283
284 41
		return $sPath;
285
	}
286
}
287