Skip to content

Commit

Permalink
Merge pull request #148 from augustohp/develop
Browse files Browse the repository at this point in the history
Allow internationalized domains and skip TLD check.
  • Loading branch information
Augusto Pascutti committed Feb 20, 2014
2 parents 9acc778 + 9ec85c3 commit 979c069
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 56 deletions.
49 changes: 16 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -708,20 +708,27 @@ See also:
* v::consonant()

#### v::domain()
#### v::domain($checkTLD=true)

Validates domain names.

v::domain()->validate('google.com');

You can skip *top level domain* (TLD) checks to validate internal
domain names:

v::domain(false)->validate('dev.machine.local')

This is a composite validator, it validates several rules
internally:

* If input is an IP address, it validates
* If input contains whitespace, it fails
* If input not contains any dot, it fails
* If input has less than two parts, it fails
* Input must end with a top-level-domain to pass
* Each part must be alphanumeric and not start with an hyphen
* If input is an IP address, it validates.
* If input contains whitespace, it fails.
* If input not contains any dot, it fails.
* If input has less than two parts, it fails.
* Input must end with a top-level-domain to pass (if not skipped).
* Each part must be alphanumeric and not start with an hyphen.
* [PunnyCode][] is accepted for [Internationalizing Domain Names in Applications][IDNA].

Messages for this validator will reflect rules above.

Expand Down Expand Up @@ -1466,7 +1473,7 @@ See also

#### v::uploaded()

Validates if the given data is a file was uploaded via HTTP POST.
Validates if the given data is a file that was uploaded via HTTP POST.

v::uploaded()->validate('/path/of/an/uploaded/file'); //true

Expand Down Expand Up @@ -1561,29 +1568,5 @@ See also:

* v::sf()



























[PunnyCode]: http://en.wikipedia.org/wiki/Punycode "Wikipedia: Punnycode"
[IDNA]: http://en.wikipedia.org/wiki/Internationalized_domain_name#Internationalizing_Domain_Names_in_Applications "Wikipedia: Internationalized domain name"
39 changes: 25 additions & 14 deletions library/Respect/Validation/Rules/Domain.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,44 @@

class Domain extends AbstractComposite
{
private $ip,
$tld,
$checks = array(),
$otherParts;
protected $tld;
protected $checks = array();
protected $otherParts;

public function __construct()
public function __construct($tldCheck=true)
{
$this->ip = new Ip();
$this->checks[] = new NoWhitespace();
$this->checks[] = new Contains('.');
$this->checks[] = new Not(new Contains('--'));
$this->checks[] = new OneOf(new Not(new Contains('--')),
new AllOf(new StartsWith('xn--'),
new Callback(function ($str) {
return substr_count($str, "--") == 1;
})));
$this->checks[] = new Length(3, null);
$this->tld = new Tld();
$this->TldCheck($tldCheck);
$this->otherParts = new AllOf(
new Alnum('-'),
new Not(new StartsWith('-'))
);
}

public function tldCheck($do=true)
{
if($do === true) {
$this->tld = new Tld();
} else {
$this->tld = new AllOf(
new Not(new StartsWith('-')),
new NoWhitespace(),
new Length(2, null)
);
}

return true;
}

public function validate($input)
{
if ($input === '' || $this->ip->validate($input))
return true;

foreach ($this->checks as $chk)
if (!$chk->validate($input))
Expand All @@ -46,8 +61,6 @@ public function validate($input)

public function assert($input)
{
if ($input === '' || $this->ip->validate($input))
return true;

$e = array();
foreach ($this->checks as $chk)
Expand Down Expand Up @@ -76,8 +89,6 @@ protected function collectAssertException(&$exceptions, $validator, $input)

public function check($input)
{
if ($input === '' || $this->ip->validate($input))
return true;

foreach ($this->checks as $chk)
$chk->check($input);
Expand Down
6 changes: 3 additions & 3 deletions library/Respect/Validation/Rules/Tld.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
class Tld extends AbstractRule
{
protected $tldList = array(
//generic
//generic - http://en.wikipedia.org/wiki/Generic_top-level_domain
'aero', 'asia', 'biz', 'cat', 'com', 'coop', 'edu', 'gov', 'info',
'int', 'jobs', 'mil', 'mobi', 'museum', 'name', 'net', 'org', 'pro',
'tel', 'travel',
'int', 'jobs', 'mil', 'mobi', 'museum', 'name', 'net', 'org', 'post', 'pro',
'tel', 'travel', 'xxx',
//country
'ac', 'ad', 'ae', 'af', 'ag', 'ai', 'al', 'am', 'ao', 'aq', 'ar', 'as',
'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh',
Expand Down
33 changes: 27 additions & 6 deletions tests/library/Respect/Validation/Rules/DomainTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php
namespace Respect\Validation\Rules;

use Respect\Validation\Validator as v;

class DomainTest extends \PHPUnit_Framework_TestCase
{
protected $object;
Expand All @@ -14,8 +16,9 @@ protected function setUp()
* @dataProvider providerForDomain
*
*/
public function testValidDomainsShouldReturnTrue($input)
public function testValidDomainsShouldReturnTrue($input, $tldcheck=true)
{
$this->object->tldCheck($tldcheck);
$this->assertTrue($this->object->__invoke($input));
$this->assertTrue($this->object->assert($input));
$this->assertTrue($this->object->check($input));
Expand All @@ -25,38 +28,56 @@ public function testValidDomainsShouldReturnTrue($input)
* @dataProvider providerForNotDomain
* @expectedException Respect\Validation\Exceptions\ValidationException
*/
public function testNotDomain($input)
public function testNotDomain($input, $tldcheck=true)
{
$this->object->tldCheck($tldcheck);
$this->assertFalse($this->object->check($input));
}

/**
* @dataProvider providerForNotDomain
* @expectedException Respect\Validation\Exceptions\DomainException
*/
public function testNotDomainCheck($input)
public function testNotDomainCheck($input, $tldcheck=true)
{
$this->object->tldCheck($tldcheck);
$this->assertFalse($this->object->assert($input));
}

public function providerForDomain()
{
return array(
array(''),
array('111111111111domain.local', false),
array('111111111111.domain.local', false),
array('example.com'),
array('xn--bcher-kva.ch'),
array('example-hyphen.com'),
array('1.2.3.4'),
);
}

public function providerForNotDomain()
{
return array(
array(null),
array('domain.local'),
array(''),
array('2222222domain.local'),
array('example--invalid.com'),
array('-example-invalid.com'),
array('example.invalid.-com'),
array('xn--bcher--kva.ch'),
array('1.2.3.256'),
array('1.2.3.4'),
);
}

/**
* @dataProvider providerForDomain
*/
public function testBuilder($validDomain, $checkTLD=true)
{
$this->assertTrue(
v::domain($checkTLD)->validate($validDomain),
sprintf('Domain "%s" should be valid. (Check TLD: %s)', $validDomain, var_export($checkTLD, true))
);
}
}
Expand Down

0 comments on commit 979c069

Please sign in to comment.