URLHelper   F
last analyzed

Complexity

Total Complexity 79

Size/Duplication

Total Lines 422
Duplicated Lines 0 %

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 79
eloc 134
c 4
b 1
f 0
dl 0
loc 422
rs 2.08

26 Methods

Rating   Name   Duplication   Size   Complexity  
A get_scheme() 0 2 3
A remove_trailing_slash() 0 5 2
A url_to_file_system() 0 6 1
A get_path_base() 0 10 4
A swap_protocol() 0 8 3
A user_trailingslashit() 0 15 5
A get_host() 0 8 5
A starts_with() 0 7 2
A get_params() 0 17 6
A file_system_to_url() 0 5 1
A is_url() 0 9 3
A remove_url_component() 0 4 1
A is_local() 0 6 3
A get_full_path() 0 5 1
B get_rel_url() 0 17 9
A get_current_url() 0 8 5
A is_internal_content() 0 12 2
A prepend_to_url() 0 24 6
A get_content_subdir() 0 4 1
A unpreslashit() 0 2 1
A preslashit() 0 5 2
A is_external_content() 0 4 2
A get_rel_path() 0 7 2
A is_absolute() 0 2 1
A is_external() 0 7 4
A remove_double_slashes() 0 9 4

How to fix   Complexity   

Complex Class

Complex classes like URLHelper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use URLHelper, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Timber;
4
5
class URLHelper {
6
7
	/**
8
	 *
9
	 *
10
	 * @return string
11
	 */
12
	public static function get_current_url() {
13
		$pageURL = self::get_scheme()."://";
14
		if ( isset($_SERVER["SERVER_PORT"]) && $_SERVER["SERVER_PORT"] && $_SERVER["SERVER_PORT"] != "80" && $_SERVER["SERVER_PORT"] != "443") {
15
			$pageURL .= self::get_host().":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
16
		} else {
17
			$pageURL .= self::get_host().$_SERVER["REQUEST_URI"];
18
		}
19
		return $pageURL;
20
	}
21
22
	/**
23
	 *
24
	 * Get url scheme
25
	 * @return string
26
	 */
27
	public static function get_scheme() {
28
		return isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
29
	}
30
31
	/**
32
	 *
33
	 * Check to see if the URL begins with the string in question
34
	 * Because it's a URL we don't care about protocol (HTTP vs HTTPS)
35
	 * Or case (so it's cAsE iNsEnSeTiVe)
36
	 * @return boolean
37
	 */
38
	public static function starts_with( $haystack, $starts_with ) {
39
		$haystack = str_replace('https', 'http', strtolower($haystack));
40
		$starts_with = str_replace('https', 'http', strtolower($starts_with));
41
		if ( 0 === strpos($haystack, $starts_with) ) {
42
			return true;
43
		}
44
		return false;
45
	}
46
47
48
	/**
49
	 *
50
	 *
51
	 * @param string  $url
52
	 * @return bool
53
	 */
54
	public static function is_url( $url ) {
55
		if ( !is_string($url) ) {
0 ignored issues
show
introduced by
The condition is_string($url) is always true.
Loading history...
56
			return false;
57
		}
58
		$url = strtolower($url);
59
		if ( strstr($url, '://') ) {
60
			return true;
61
		}
62
		return false;
63
	}
64
65
	/**
66
	 *
67
	 *
68
	 * @return string
69
	 */
70
	public static function get_path_base() {
71
		$struc = get_option('permalink_structure');
72
		$struc = explode('/', $struc);
0 ignored issues
show
Bug introduced by
It seems like $struc can also be of type false; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

72
		$struc = explode('/', /** @scrutinizer ignore-type */ $struc);
Loading history...
73
		$p = '/';
74
		foreach ( $struc as $s ) {
75
			if ( !strstr($s, '%') && strlen($s) ) {
76
				$p .= $s.'/';
77
			}
78
		}
79
		return $p;
80
	}
81
82
	/**
83
	 *
84
	 *
85
	 * @param string  $url
86
	 * @param bool    $force
87
	 * @return string
88
	 */
89
	public static function get_rel_url( $url, $force = false ) {
90
		$url_info = parse_url($url);
91
		if ( isset($url_info['host']) && $url_info['host'] != self::get_host() && !$force ) {
92
			return $url;
93
		}
94
		$link = '';
95
		if ( isset($url_info['path']) ) {
96
			$link = $url_info['path'];
97
		}
98
		if ( isset($url_info['query']) && strlen($url_info['query']) ) {
99
			$link .= '?'.$url_info['query'];
100
		}
101
		if ( isset($url_info['fragment']) && strlen($url_info['fragment']) ) {
102
			$link .= '#'.$url_info['fragment'];
103
		}
104
		$link = self::remove_double_slashes($link);
105
		return $link;
106
	}
107
108
	/**
109
	 * Some setups like HTTP_HOST, some like SERVER_NAME, it's complicated
110
	 * @link http://stackoverflow.com/questions/2297403/http-host-vs-server-name
111
	 * @return string the HTTP_HOST or SERVER_NAME
112
	 */
113
	public static function get_host() {
114
		if ( isset($_SERVER['HTTP_HOST']) && $_SERVER['HTTP_HOST'] ) {
115
			return $_SERVER['HTTP_HOST'];
116
		}
117
		if ( isset($_SERVER['SERVER_NAME']) && $_SERVER['SERVER_NAME'] ) {
118
			return $_SERVER['SERVER_NAME'];
119
		}
120
		return '';
121
	}
122
123
	/**
124
	 *
125
	 *
126
	 * @param string  $url
127
	 * @return bool
128
	 */
129
	public static function is_local( $url ) {
130
		$host = self::get_host();
131
		if ( !empty($host) && strstr($url, $host) ) {
132
			return true;
133
		}
134
		return false;
135
	}
136
137
	/**
138
	 *
139
	 *
140
	 * @param string  $src
141
	 * @return string
142
	 */
143
	public static function get_full_path( $src ) {
144
		$root = ABSPATH;
145
		$old_root_path = $root.$src;
146
		$old_root_path = str_replace('//', '/', $old_root_path);
147
		return $old_root_path;
148
	}
149
150
	/**
151
	 * Takes a url and figures out its place based in the file system based on path
152
	 * NOTE: Not fool-proof, makes a lot of assumptions about the file path
153
	 * matching the URL path
154
	 *
155
	 * @param string  $url
156
	 * @return string
157
	 */
158
	public static function url_to_file_system( $url ) {
159
		$url_parts = parse_url($url);
160
		$url_parts['path'] = apply_filters('timber/URLHelper/url_to_file_system/path', $url_parts['path']);
161
		$path = ABSPATH.$url_parts['path'];
162
		$path = str_replace('//', '/', $path);
163
		return $path;
164
	}
165
166
	/**
167
	 * @param string $fs
168
	 */
169
	public static function file_system_to_url( $fs ) {
170
		$relative_path = self::get_rel_path($fs);
171
		$home = home_url('/'.$relative_path);
172
		$home = apply_filters('timber/URLHelper/file_system_to_url', $home);
173
		return $home;
174
	}
175
176
	/**
177
	 * Get the path to the content directory relative to the site.
178
	 * This replaces the WP_CONTENT_SUBDIR constant
179
	 * @return string (ex: /wp-content or /content)
180
	 */
181
	public static function get_content_subdir() {
182
		$home_url = get_home_url();
183
		$home_url = apply_filters('timber/URLHelper/get_content_subdir/home_url', $home_url);
184
		return str_replace($home_url, '', WP_CONTENT_URL);
185
	}
186
187
	/**
188
	 *
189
	 *
190
	 * @param string  $src
191
	 * @return string
192
	 */
193
	public static function get_rel_path( $src ) {
194
		if ( strstr($src, ABSPATH) ) {
195
			return str_replace(ABSPATH, '', $src);
196
		}
197
		//its outside the wordpress directory, alternate setups:
198
		$src = str_replace(WP_CONTENT_DIR, '', $src);
199
		return self::get_content_subdir().$src;
200
	}
201
202
	/**
203
	 *
204
	 *
205
	 * @param string  $url
206
	 * @return string
207
	 */
208
	public static function remove_double_slashes( $url ) {
209
		$url = str_replace('//', '/', $url);
210
		$schemes_whitelist = apply_filters( 'timber/url/schemes-whitelist', array( 'http', 'https', 's3', 'gs' )  );
211
		foreach ( $schemes_whitelist as $scheme ) {
212
			if ( strstr($url, $scheme . ':') && !strstr($url, $scheme . '://') ) {
213
				$url = str_replace( $scheme . ':/', $scheme . '://', $url );
214
			}
215
		}
216
		return $url;
217
	}
218
219
	/**
220
	 *
221
	 *
222
	 * @param string  $url
223
	 * @param string  $path
224
	 * @return string
225
	 */
226
	public static function prepend_to_url( $url, $path ) {
227
		if ( strstr(strtolower($url), 'http') ) {
228
			$url_parts = parse_url($url);
229
			$url = $url_parts['scheme'].'://'.$url_parts['host'];
230
231
			if ( isset($url_parts['port']) ) {
232
				$url .= ':'.$url_parts['port'];
233
			}
234
235
			$url .= $path;
236
237
			if ( isset($url_parts['path']) ) {
238
				$url .= $url_parts['path'];
239
			}
240
			if ( isset($url_parts['query']) ) {
241
				$url .= '?'.$url_parts['query'];
242
			}
243
			if ( isset($url_parts['fragment']) ) {
244
				$url .= '#'.$url_parts['fragment'];
245
			}
246
		} else {
247
			$url = $url.$path;
248
		}
249
		return self::remove_double_slashes($url);
250
	}
251
252
	/**
253
	 *
254
	 *
255
	 * @param string  $path
256
	 * @return string
257
	 */
258
	public static function preslashit( $path ) {
259
		if ( strpos($path, '/') != 0 ) {
260
			$path = '/'.$path;
261
		}
262
		return $path;
263
	}
264
265
	/**
266
	 *
267
	 *
268
	 * @param string  $path
269
	 * @return string
270
	 */
271
	public static function unpreslashit( $path ) {
272
		return ltrim($path, '/');
273
	}
274
275
	/**
276
	 * This will evaluate wheter a URL is at an aboslute location (like http://example.org/whatever)
277
	 *
278
	 * @param string $path
279
	 * @return boolean true if $path is an absolute url, false if relative.
280
	 */
281
	public static function is_absolute( $path ) {
282
		return (boolean) (strstr($path, 'http'));
283
	}
284
285
286
	/**
287
	 * This function is slightly different from the one below in the case of:
288
	 * an image hosted on the same domain BUT on a different site than the
289
	 * Wordpress install will be reported as external content.
290
	 *
291
	 * @param string  $url a URL to evaluate against
292
	 * @return boolean if $url points to an external location returns true
293
	 */
294
	public static function is_external_content( $url ) {
295
		$is_external = self::is_absolute($url) && !self::is_internal_content($url);
296
297
		return $is_external;
298
	}
299
300
	/**
301
	 * @param string $url
302
	 */
303
	private static function is_internal_content( $url ) {
304
		// using content_url() instead of site_url or home_url is IMPORTANT
305
		// otherwise you run into errors with sites that:
306
		// 1. use WPML plugin
307
		// 2. or redefine content directory
308
		$is_content_url = strstr($url, content_url());
309
310
		// this case covers when the upload directory has been redefined
311
		$upload_dir = wp_upload_dir();
312
		$is_upload_url = strstr($url, $upload_dir['baseurl']);
313
314
		return $is_content_url || $is_upload_url;
315
	}
316
317
	/**
318
	 * Checks if URL is external or internal.
319
	 * Works with domains, subdomains and protocol relative domains.
320
	 *
321
	 * @param string $url Url.
322
	 * @return bool     true if $path is an external url, false if relative or local.
323
	 *                  true if it's a subdomain (http://cdn.example.org = true)
324
	 */
325
	public static function is_external( $url ) {
326
		$has_http  = strstr(strtolower($url), 'http') || strstr(strtolower($url), '//');
327
		$on_domain = strstr($url, self::get_host());
328
		if ( $has_http && ! $on_domain ) {
329
			return true;
330
		}
331
		return false;
332
	}
333
334
	/**
335
	 * Pass links through untrailingslashit unless they are a single /
336
	 *
337
	 * @param string  $link
338
	 * @return string
339
	 */
340
	public static function remove_trailing_slash( $link ) {
341
		if ( $link != "/" ) {
342
			$link = untrailingslashit($link);
343
		}
344
		return $link;
345
	}
346
347
	/**
348
	 * Removes the subcomponent of a URL regardless of protocol
349
	 * @since 1.3.3
350
	 * @author jarednova
351
	 * @param string $haystack ex: http://example.org/wp-content/uploads/dog.jpg
352
	 * @param string $needle ex: http://example.org/wp-content
353
	 * @return string
354
	 */
355
	public static function remove_url_component( $haystack, $needle ) {
356
		$haystack = str_replace($needle, '', $haystack);
357
		$needle = self::swap_protocol($needle);
358
		return str_replace($needle, '', $haystack);
359
	}
360
361
362
	/**
363
	 * Swaps whatever protocol of a URL is sent. http becomes https and vice versa
364
	 * @since 1.3.3
365
	 * @author jarednova
366
	 * @param string $url ex: http://example.org/wp-content/uploads/dog.jpg
367
	 * @return string ex: https://example.org/wp-content/uploads/dog.jpg
368
	 */
369
	public static function swap_protocol( $url ) {
370
		if ( stristr($url, 'http:') ) {
371
			return str_replace('http:', 'https:', $url);
372
		}
373
		if ( stristr($url, 'https:') ) {
374
			return str_replace('https:', 'http:', $url);
375
		}
376
		return $url;
377
	}
378
379
	/**
380
	 * Pass links through user_trailingslashit handling query strings properly
381
	 *
382
	 * @param string $link
383
	 * @return string
384
	 * */
385
	public static function user_trailingslashit( $link ) {
386
		$link_parts = parse_url($link);
387
388
		if ( !$link_parts ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $link_parts of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
389
			return $link;
390
		}
391
392
		if ( isset($link_parts['path']) && $link_parts['path'] != '/' ) {
393
			$new_path = user_trailingslashit($link_parts['path']);
394
395
			if ( $new_path != $link_parts['path'] ) {
396
				$link = str_replace($link_parts['path'], $new_path, $link);
397
			}
398
		}
399
		return $link;
400
	}
401
402
	/**
403
	 * Returns the url parameters, for example for url http://example.org/blog/post/news/2014/whatever
404
	 * this will return array('blog', 'post', 'news', '2014', 'whatever');
405
	 * OR if sent an integer like: TimberUrlHelper::get_params(2); this will return 'news';
406
	 *
407
	 * @param int $i the position of the parameter to grab.
408
	 * @return array|string
409
	 */
410
	public static function get_params( $i = false ) {
411
		$args = explode('/', trim(strtolower($_SERVER['REQUEST_URI'])));
412
		$newargs = array();
413
		foreach ( $args as $arg ) {
414
			if ( strlen($arg) ) {
415
				$newargs[] = $arg;
416
			}
417
		}
418
		if ( $i === false ) {
419
			return $newargs;
420
		}
421
		if ( $i < 0 ) {
422
			//count from end
423
			$i = count($newargs) + $i;
424
		}
425
		if ( isset($newargs[$i]) ) {
426
			return $newargs[$i];
427
		}
428
	}
429
430
}
431