Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
3 / 3 |
CRAP | |
100.00% |
50 / 50 |
IpAddress | |
100.00% |
1 / 1 |
|
100.00% |
3 / 3 |
13 | |
100.00% |
50 / 50 |
__construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
validate | |
100.00% |
1 / 1 |
11 | |
100.00% |
46 / 46 |
|||
getInverseError | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
<?php | |
namespace Verja\Validator; | |
use Verja\Error; | |
use Verja\Validator; | |
class IpAddress extends Validator | |
{ | |
const VERSION_ANY = 'any'; | |
const VERSION_4 = 'v4'; | |
const VERSION_6 = 'v6'; | |
const RANGE_ANY = 'any'; | |
const RANGE_PUBLIC = 'public'; | |
const RANGE_UNRESERVED = 'unreserved'; | |
const RANGE_PRIVATE = 'private'; | |
/** @var string */ | |
protected $version; | |
/** @var string */ | |
protected $range; | |
/** | |
* IpAddress constructor. | |
* | |
* @param string $version 'any' (default), 'v4' or 'v6' | |
* @param string $range 'any' (default), 'public', 'public,unreserved' or 'private' | |
*/ | |
public function __construct(string $version = self::VERSION_ANY, string $range = self::RANGE_ANY) | |
{ | |
$this->version = $version; | |
$this->range = $range; | |
} | |
/** | |
* Validate $value | |
* | |
* @param mixed $value | |
* @param array $context | |
* @return bool | |
*/ | |
public function validate($value, array $context = []): bool | |
{ | |
$flags = 0; | |
$ipName = 'ip address'; | |
if ($this->version === self::VERSION_6) { | |
$flags = $flags | FILTER_FLAG_IPV6; | |
$ipName = 'ip-v6 address'; | |
} elseif ($this->version === self::VERSION_4) { | |
$flags = $flags | FILTER_FLAG_IPV4; | |
$ipName = 'ip-v4 address'; | |
} | |
$parameters = [ | |
'version' => $this->version, | |
'range' => $this->range, | |
]; | |
if (!filter_var($value, FILTER_VALIDATE_IP, $flags)) { | |
// not a valid ip address | |
$this->error = new Error( | |
'NO_IP_ADDRESS', | |
$value, | |
sprintf('value should be an %s', $ipName), | |
$parameters | |
); | |
return false; | |
} | |
if ($this->range !== self::RANGE_ANY) { | |
if (strpos($this->range, self::RANGE_PUBLIC) !== false) { | |
$flags = $flags | FILTER_FLAG_NO_PRIV_RANGE; | |
if (!filter_var($value, FILTER_VALIDATE_IP, $flags)) { | |
// not a public ip address | |
$this->error = new Error( | |
'NO_PUBLIC_IP_ADDRESS', | |
$value, | |
sprintf('value should be a public %s', $ipName), | |
$parameters | |
); | |
return false; | |
} elseif (strpos($this->range, self::RANGE_UNRESERVED) !== false) { | |
$flags = $flags | FILTER_FLAG_NO_RES_RANGE; | |
if (!filter_var($value, FILTER_VALIDATE_IP, $flags)) { | |
// reserved ip address | |
$this->error = new Error( | |
'IS_RESERVED_IP_ADDRESS', | |
$value, | |
sprintf('value should not be a reserved %s', $ipName), | |
$parameters | |
); | |
return false; | |
} | |
} | |
} | |
if ($this->range === self::RANGE_PRIVATE) { | |
$flags = $flags | FILTER_FLAG_NO_PRIV_RANGE; | |
if (filter_var($value, FILTER_VALIDATE_IP, $flags)) { | |
// public ip address | |
$this->error = new Error( | |
'IS_PUBLIC_IP_ADDRESS', | |
$value, | |
sprintf('value should not be a public %s', $ipName), | |
$parameters | |
); | |
return false; | |
} | |
} | |
} | |
return true; | |
} | |
public function getInverseError($value) | |
{ | |
return new Error('IS_IP_ADDRESS', $value, 'value should not be an ip address'); | |
} | |
} |