Completed
Push — master ( 49e9a0...fa7091 )
by Jan-Petter
02:11
created

UrlTools   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 14
c 1
b 0
f 0
lcom 1
cbo 1
dl 0
loc 110
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
B urlEncode() 0 28 2
A urlBase() 0 12 3
A urlValidate() 0 9 4
A urlValidateHost() 0 9 4
A urlValidateScheme() 0 10 1
1
<?php
2
namespace vipnytt\RobotsTxtParser\Modules;
3
4
use vipnytt\RobotsTxtParser\Exceptions\ClientException;
5
6
/**
7
 * Trait UrlTools
8
 *
9
 * @package vipnytt\RobotsTxtParser\Modules
10
 */
11
trait UrlTools
12
{
13
    /**
14
     * URL encoder according to RFC 3986
15
     * Returns a string containing the encoded URL with disallowed characters converted to their percentage encodings.
16
     * @link http://publicmind.in/blog/url-encoding/
17
     *
18
     * @param string $url
19
     * @return string
20
     */
21
    protected function urlEncode($url)
22
    {
23
        $reserved = [
24
            ":" => '!%3A!ui',
25
            "/" => '!%2F!ui',
26
            "?" => '!%3F!ui',
27
            "#" => '!%23!ui',
28
            "[" => '!%5B!ui',
29
            "]" => '!%5D!ui',
30
            "@" => '!%40!ui',
31
            "!" => '!%21!ui',
32
            "$" => '!%24!ui',
33
            "&" => '!%26!ui',
34
            "'" => '!%27!ui',
35
            "(" => '!%28!ui',
36
            ")" => '!%29!ui',
37
            "*" => '!%2A!ui',
38
            "+" => '!%2B!ui',
39
            "," => '!%2C!ui',
40
            ";" => '!%3B!ui',
41
            "=" => '!%3D!ui',
42
            "%" => '!%25!ui'
43
        ];
44
        foreach ($reserved as $replace => $pattern) {
45
            $url = mb_ereg_replace($pattern, $replace, $url);
46
        }
47
        return $url;
48
    }
49
50
    /**
51
     * Base URL
52
     *
53
     * @param string $url
54
     * @return string
55
     * @throws ClientException
56
     */
57
    protected function urlBase($url)
58
    {
59
        if ($this->urlValidate($url) === false) {
60
            throw new ClientException('Invalid URL');
61
        }
62
        $parts = [
63
            'scheme' => parse_url($url, PHP_URL_SCHEME),
64
            'host' => parse_url($url, PHP_URL_HOST),
65
        ];
66
        $parts['port'] = is_int($port = parse_url($url, PHP_URL_PORT)) ? $port : getservbyname($parts['scheme'], 'tcp');
67
        return $parts['scheme'] . '://' . $parts['host'] . ':' . $parts['port'];
68
    }
69
70
    /**
71
     * Validate URL
72
     *
73
     * @param string $url
74
     * @return bool
75
     */
76
    protected function urlValidate($url)
77
    {
78
        return (
79
            filter_var($url, FILTER_VALIDATE_URL) &&
80
            ($parsed = parse_url($url)) !== false &&
81
            $this->urlValidateHost($parsed['host']) &&
82
            $this->urlValidateScheme($parsed['scheme'])
83
        );
84
    }
85
86
    /**
87
     * Validate host name
88
     *
89
     * @link http://stackoverflow.com/questions/1755144/how-to-validate-domain-name-in-php
90
     *
91
     * @param  string $host
92
     * @return bool
93
     */
94
    protected static function urlValidateHost($host)
95
    {
96
        return (
97
            mb_ereg_match('^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$', $host) && //valid chars check
98
            mb_ereg_match('^.{1,253}$', $host) && //overall length check
99
            mb_ereg_match('^[^\.]{1,63}(\.[^\.]{1,63})*$', $host) && //length of each label
100
            !filter_var($host, FILTER_VALIDATE_IP) //is not an IP address
101
        );
102
    }
103
104
    /**
105
     * Validate URL scheme
106
     *
107
     * @param  string $scheme
108
     * @return bool
109
     */
110
    protected static function urlValidateScheme($scheme)
111
    {
112
        return in_array($scheme, [
113
                'http',
114
                'https',
115
                'ftp',
116
                'sftp',
117
            ]
118
        );
119
    }
120
}
121