Passed
Pull Request — master (#24)
by Alfred
02:18
created

GeoipNetwork   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 22
eloc 47
c 2
b 0
f 0
dl 0
loc 115
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
B getIPAddress() 0 17 7
A ip2Integer() 0 9 2
A validateAddress() 0 11 3
A expandAddress() 0 16 4
A ipVersion() 0 10 4
A __construct() 0 5 2
1
<?php
2
3
namespace geolocation\bin;
4
5
class GeoipNetwork
6
{
7
    /**
8
     * @var string $ipAddress
9
    **/
10
    private $ipAddress=null;
11
    /**
12
     * Class constructor.
13
     *
14
     * @param string $ipAddress
15
     */
16
    public function __construct(string $ipAddress=null)
17
    {
18
        $ipAddress || $ipAddress = $this->getIPAddress();
19
        $this->validateAddress($ipAddress);
20
        $this->ipAddress = $ipAddress;
21
    }
22
    /**
23
     * Auto Get the current visitor IP Address
24
     * @return string
25
     */
26
    public function getIPAddress()
27
    {
28
        $ipAddress = null;
29
        $serverIPKeys =['HTTP_X_COMING_FROM', 'HTTP_FORWARDED', 'HTTP_FORWARDED_FOR', 'HTTP_X_CLUSTER_CLIENT_IP',
30
                        'HTTP_X_FORWARDED', 'HTTP_VIA', 'HTTP_CLIENT_IP','HTTP_X_FORWARDED_FOR','REMOTE_ADDR'];
31
        foreach ($serverIPKeys as $IPKey):
32
            if (array_key_exists($IPKey, $_SERVER)) {
33
                if (!strlen($_SERVER[$IPKey])) { continue; }
34
                $ipAddress = $_SERVER[$IPKey];
35
                break;
36
            }
37
        endforeach;
38
        if (!is_null($ipAddress) && ($commaPos = strpos($ipAddress, ',')) > 0)
39
        {
40
            $ipAddress = substr($ipAddress, 0, ($commaPos - 1));
41
        }
42
        return $ipAddress?:'0.0.0.0';
43
    }
44
    /**
45
     * If IPV6, Returns the IP in it's fullest format.
46
     * @example
47
     *          ::1              => 0000:0000:0000:0000:0000:0000:0000:0001
48
     *          220F::127.0.0.1  => 220F:0000:0000:0000:0000:0000:7F00:0001
49
     *          2F:A1::1         => 002F:00A1:0000:0000:0000:0000:0000:0001
50
     * @param $ipAddress
51
     * @return mixed|string
52
     */
53
    public function expandAddress($ipAddress)
54
    {
55
        $ipAddress || $ipAddress = $this->ipAddress;
56
        try
57
        {
58
            $this->validateAddress($ipAddress);
59
            if (strpos($ipAddress, ':') !== false) // IPv6 address
60
            {
61
                $hex = unpack('H*hex', inet_pton($ipAddress));
62
                $ipAddress = substr(preg_replace('/([A-f0-9]{4})/', "$1:", $hex['hex']), 0, -1);
63
                $ipAddress = strtoupper($ipAddress);
64
            }
65
        } catch (\Throwable $th) {
66
            trigger_error($th->getMessage(), E_USER_ERROR);
67
        }
68
        return $ipAddress;
69
    }
70
    /**
71
     * Convert both IPV4 and IPv6 address to int|bigint
72
     *
73
     * @param string $ipAddress
74
     * @return int
75
     */
76
    public function ip2Integer(string $ipAddress)
77
    {
78
        $ipAddress = $this->expandAddress($ipAddress);
79
        if (strpos($ipAddress, ':') !== false):
80
            $bin = inet_pton($ipAddress) ;
81
            $ints = unpack('J2', $bin) ;
82
            return $ints[1] ;
83
        endif;
84
        return ip2long($ipAddress);
85
    }
86
    /**
87
     * Check IP address validity
88
     *
89
     * @param string $ipAddress
90
     * @return string
91
     */
92
    public function validateAddress(string $ipAddress)
93
    {
94
        try
95
        {
96
            if (!filter_var($ipAddress, FILTER_VALIDATE_IP, [FILTER_FLAG_IPV4|FILTER_FLAG_IPV6])) {
97
                throw new \Throwable('Invalid IP given');
0 ignored issues
show
Unused Code introduced by
The call to Throwable::__construct() has too many arguments starting with 'Invalid IP given'. ( Ignorable by Annotation )

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

97
                throw /** @scrutinizer ignore-call */ new \Throwable('Invalid IP given');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
98
            }
99
        } catch (\Throwable $th) {
100
            trigger_error($th->getMessage(), E_USER_ERROR);
101
        }
102
        return $ipAddress;
103
    }
104
    /**
105
     * Get IP version of given address
106
     *
107
     * @param string $ipAddress
108
     * @return integer
109
     */
110
    public function ipVersion(string $ipAddress)
111
    {
112
        $ipAddress || $ipAddress = $this->getIPAddress();
113
        try
114
        {
115
            $ipAddress = $this->expandAddress($ipAddress);
116
            if (strpos($ipAddress, ':') !== false) {return 6;}
117
            return 4;
118
        } catch (\Throwable $th) {
119
            trigger_error($th->getMessage(), E_USER_ERROR);
120
        }
121
    }
122
}
123