Requests_IPv6::compress()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
nc 4
nop 1
dl 0
loc 29
rs 8.439
c 0
b 0
f 0
1
<?php
2
/**
3
 * Class to validate and to work with IPv6 addresses
4
 *
5
 * @package Requests
6
 * @subpackage Utilities
7
 */
8
9
/**
10
 * Class to validate and to work with IPv6 addresses
11
 *
12
 * This was originally based on the PEAR class of the same name, but has been
13
 * entirely rewritten.
14
 *
15
 * @package Requests
16
 * @subpackage Utilities
17
 */
18
class Requests_IPv6 {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
Coding Style introduced by
This class is not in CamelCase format.

Classes in PHP are usually named in CamelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. The whole name starts with a capital letter as well.

Thus the name database provider becomes DatabaseProvider.

Loading history...
19
	/**
20
	 * Uncompresses an IPv6 address
21
	 *
22
	 * RFC 4291 allows you to compress consecutive zero pieces in an address to
23
	 * '::'. This method expects a valid IPv6 address and expands the '::' to
24
	 * the required number of zero pieces.
25
	 *
26
	 * Example:  FF01::101   ->  FF01:0:0:0:0:0:0:101
27
	 *           ::1         ->  0:0:0:0:0:0:0:1
28
	 *
29
	 * @author Alexander Merz <[email protected]>
30
	 * @author elfrink at introweb dot nl
31
	 * @author Josh Peck <jmp at joshpeck dot org>
32
	 * @copyright 2003-2005 The PHP Group
33
	 * @license http://www.opensource.org/licenses/bsd-license.php
34
	 * @param string $ip An IPv6 address
35
	 * @return string The uncompressed IPv6 address
36
	 */
37
	public static function uncompress($ip) {
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ip. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
38
		if (substr_count($ip, '::') !== 1) {
39
			return $ip;
40
		}
41
42
		list($ip1, $ip2) = explode('::', $ip);
43
		$c1 = ($ip1 === '') ? -1 : substr_count($ip1, ':');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $c1. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 14 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
44
		$c2 = ($ip2 === '') ? -1 : substr_count($ip2, ':');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $c2. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 14 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
45
46
		if (strpos($ip2, '.') !== false) {
47
			$c2++;
48
		}
49
		// ::
50
		if ($c1 === -1 && $c2 === -1) {
51
			$ip = '0:0:0:0:0:0:0:0';
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $ip. This often makes code more readable.
Loading history...
52
		}
53
		// ::xxx
54
		else if ($c1 === -1) {
55
			$fill = str_repeat('0:', 7 - $c2);
56
			$ip = str_replace('::', $fill, $ip);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $ip. This often makes code more readable.
Loading history...
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
57
		}
58
		// xxx::
59
		else if ($c2 === -1) {
60
			$fill = str_repeat(':0', 7 - $c1);
61
			$ip = str_replace('::', $fill, $ip);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $ip. This often makes code more readable.
Loading history...
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
62
		}
63
		// xxx::xxx
64
		else {
65
			$fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
66
			$ip = str_replace('::', $fill, $ip);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $ip. This often makes code more readable.
Loading history...
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
67
		}
68
		return $ip;
69
	}
70
71
	/**
72
	 * Compresses an IPv6 address
73
	 *
74
	 * RFC 4291 allows you to compress consecutive zero pieces in an address to
75
	 * '::'. This method expects a valid IPv6 address and compresses consecutive
76
	 * zero pieces to '::'.
77
	 *
78
	 * Example:  FF01:0:0:0:0:0:0:101   ->  FF01::101
79
	 *           0:0:0:0:0:0:0:1        ->  ::1
80
	 *
81
	 * @see uncompress()
82
	 * @param string $ip An IPv6 address
83
	 * @return string The compressed IPv6 address
84
	 */
85
	public static function compress($ip) {
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ip. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
86
		// Prepare the IP to be compressed
87
		$ip = self::uncompress($ip);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $ip. This often makes code more readable.
Loading history...
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
88
		$ip_parts = self::split_v6_v4($ip);
89
90
		// Replace all leading zeros
91
		$ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
92
93
		// Find bunches of zeros
94
		if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE)) {
95
			$max = 0;
96
			$pos = null;
97
			foreach ($matches[0] as $match) {
98
				if (strlen($match[0]) > $max) {
99
					$max = strlen($match[0]);
100
					$pos = $match[1];
101
				}
102
			}
103
104
			$ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
105
		}
106
107
		if ($ip_parts[1] !== '') {
108
			return implode(':', $ip_parts);
109
		}
110
		else {
111
			return $ip_parts[0];
112
		}
113
	}
114
115
	/**
116
	 * Splits an IPv6 address into the IPv6 and IPv4 representation parts
117
	 *
118
	 * RFC 4291 allows you to represent the last two parts of an IPv6 address
119
	 * using the standard IPv4 representation
120
	 *
121
	 * Example:  0:0:0:0:0:0:13.1.68.3
122
	 *           0:0:0:0:0:FFFF:129.144.52.38
123
	 *
124
	 * @param string $ip An IPv6 address
125
	 * @return string[] [0] contains the IPv6 represented part, and [1] the IPv4 represented part
126
	 */
127
	protected static function split_v6_v4($ip) {
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ip. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
128
		if (strpos($ip, '.') !== false) {
129
			$pos = strrpos($ip, ':');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
130
			$ipv6_part = substr($ip, 0, $pos);
131
			$ipv4_part = substr($ip, $pos + 1);
132
			return array($ipv6_part, $ipv4_part);
133
		}
134
		else {
135
			return array($ip, '');
136
		}
137
	}
138
139
	/**
140
	 * Checks an IPv6 address
141
	 *
142
	 * Checks if the given IP is a valid IPv6 address
143
	 *
144
	 * @param string $ip An IPv6 address
145
	 * @return bool true if $ip is a valid IPv6 address
146
	 */
147
	public static function check_ipv6($ip) {
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ip. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
148
		$ip = self::uncompress($ip);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $ip. This often makes code more readable.
Loading history...
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 16 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
149
		list($ipv6, $ipv4) = self::split_v6_v4($ip);
150
		$ipv6 = explode(':', $ipv6);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 14 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
151
		$ipv4 = explode('.', $ipv4);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 14 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
152
		if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4) {
153
			foreach ($ipv6 as $ipv6_part) {
154
				// The section can't be empty
155
				if ($ipv6_part === '') {
156
					return false;
157
				}
158
159
				// Nor can it be over four characters
160
				if (strlen($ipv6_part) > 4) {
161
					return false;
162
				}
163
164
				// Remove leading zeros (this is safe because of the above)
165
				$ipv6_part = ltrim($ipv6_part, '0');
166
				if ($ipv6_part === '') {
167
					$ipv6_part = '0';
168
				}
169
170
				// Check the value is valid
171
				$value = hexdec($ipv6_part);
172
				if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF) {
173
					return false;
174
				}
175
			}
176
			if (count($ipv4) === 4) {
177
				foreach ($ipv4 as $ipv4_part) {
178
					$value = (int) $ipv4_part;
179
					if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF) {
180
						return false;
181
					}
182
				}
183
			}
184
			return true;
185
		}
186
		else {
187
			return false;
188
		}
189
	}
190
}
0 ignored issues
show
Coding Style introduced by
As per coding style, files should not end with a newline character.

This check marks files that end in a newline character, i.e. an empy line.

Loading history...
191