Passed
Push — codeclean ( dc06b1...eb864a )
by Paweł
02:30
created

Url::normalizeUrl()   C

Complexity

Conditions 12
Paths 66

Size

Total Lines 31
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 12
eloc 20
c 3
b 1
f 0
nc 66
nop 1
dl 0
loc 31
rs 6.9666

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
declare(strict_types=1);
3
4
namespace Wszetko\Sitemap\Helpers;
5
6
/**
7
 * Class Url
8
 *
9
 * @package Wszetko\Sitemap\Helpers
10
 */
11
class Url
12
{
13
    /**
14
     * @param string $url
15
     *
16
     * @return bool|string
17
     *
18
     * @see https://bugs.php.net/bug.php?id=52923
19
     * @see https://www.php.net/manual/en/function.parse-url.php#114817
20
     */
21
    public static function normalizeUrl(string $url)
22
    {
23
        $encodedUrl = preg_replace_callback(
24
            '%[^:/@?&=#]+%usD',
25
            function ($matches) {
26
                return urlencode($matches[0]);
27
            },
28
            $url
29
        );
30
31
        $url = parse_url($encodedUrl);
32
33
        if (!$url || !isset($url['host'])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $url 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...
34
            return false;
35
        }
36
37
        $url = array_map('urldecode', $url);
38
        $url['host'] = idn_to_ascii($url['host'], IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
39
40
        if (empty($url['scheme']) || !is_string($url['host']) || !self::checkDomain($url['host'])) {
41
            return false;
42
        }
43
44
        return
45
            $url['scheme'] . '://'
46
            . (isset($url['user']) ? $url['user'] . ((isset($url['pass'])) ? ':' . $url['pass'] : '') . '@' : '')
47
            . $url['host']
48
            . ((isset($url['port'])) ? ':' . $url['port'] : '')
49
            . ((isset($url['path'])) ? $url['path'] : '')
50
            . ((isset($url['query'])) ? '?' . $url['query'] : '')
51
            . ((isset($url['fragment'])) ? '#' . $url['fragment'] : '');
52
    }
53
54
    /**
55
     * @param string $domain
56
     *
57
     * @return bool
58
     */
59
    public static function checkDomain(string $domain): bool
60
    {
61
        $domain = idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
62
63
        return (bool)filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME);
64
    }
65
}
66