Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd930263

Browse files
committed
Added HostnameValidator
1 parent519ba3c commitd930263

File tree

3 files changed

+275
-0
lines changed

3 files changed

+275
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Validator\Constraints;
13+
14+
useSymfony\Component\Validator\Constraint;
15+
16+
/**
17+
* @Annotation
18+
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
19+
*
20+
* @author Dmitrii Poddubnyi <dpoddubny@gmail.com>
21+
*/
22+
class Hostnameextends Constraint
23+
{
24+
constINVALID_HOSTNAME_ERROR ='7057ffdb-0af4-4f7e-bd5e-e9acfa6d7a2d';
25+
26+
protectedstatic$errorNames = [
27+
self::INVALID_HOSTNAME_ERROR =>'INVALID_FORMAT_ERROR',
28+
];
29+
30+
public$message ='This value is not a valid hostname';
31+
public$requireTld =true;
32+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Validator\Constraints;
13+
14+
useSymfony\Component\Validator\Constraint;
15+
useSymfony\Component\Validator\ConstraintValidator;
16+
useSymfony\Component\Validator\Exception\UnexpectedTypeException;
17+
useSymfony\Component\Validator\Exception\UnexpectedValueException;
18+
19+
/**
20+
* @author Dmitrii Poddubnyi <dpoddubny@gmail.com>
21+
*/
22+
class HostnameValidatorextends ConstraintValidator
23+
{
24+
/**
25+
* https://tools.ietf.org/html/rfc2606
26+
*/
27+
privateconstRESERVED_TLDS = [
28+
'example',
29+
'invalid',
30+
'localhost',
31+
'test',
32+
];
33+
34+
publicfunctionvalidate($value,Constraint$constraint)
35+
{
36+
if (!$constraintinstanceof Hostname) {
37+
thrownewUnexpectedTypeException($constraint,__NAMESPACE__.'\Domain');
38+
}
39+
40+
if (null ===$value ||'' ===$value) {
41+
return;
42+
}
43+
44+
if (!is_scalar($value) && !(\is_object($value) &&method_exists($value,'__toString'))) {
45+
thrownewUnexpectedValueException($value,'string');
46+
}
47+
48+
$value = (string)$value;
49+
if ('' ===$value) {
50+
return;
51+
}
52+
if (!$this->isValid($value) || ($constraint->requireTld && !$this->hasValidTld($value))) {
53+
$this->context->buildViolation($constraint->message)
54+
->setParameter('{{ value }}',$this->formatValue($value))
55+
->setCode(Hostname::INVALID_HOSTNAME_ERROR)
56+
->addViolation();
57+
}
58+
}
59+
60+
privatefunctionisValid(string$domain):bool
61+
{
62+
returnfalse !==filter_var($domain,FILTER_VALIDATE_DOMAIN,FILTER_FLAG_HOSTNAME);
63+
}
64+
65+
privatefunctionhasValidTld(string$domain):bool
66+
{
67+
returnfalse !==mb_strpos($domain,'.') && !$this->hasReservedTld($domain);
68+
}
69+
70+
privatefunctionhasReservedTld(string$domain):bool
71+
{
72+
$parts =explode('.',$domain);
73+
$domain =end($parts);
74+
$domain =mb_strtolower($domain);
75+
76+
return\in_array($domain,self::RESERVED_TLDS,true);
77+
}
78+
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Validator\Tests\Constraints;
13+
14+
useSymfony\Component\Validator\Constraints\Hostname;
15+
useSymfony\Component\Validator\Constraints\HostnameValidator;
16+
useSymfony\Component\Validator\Test\ConstraintValidatorTestCase;
17+
18+
/**
19+
* @author Dmitrii Poddubnyi <dpoddubny@gmail.com>
20+
*/
21+
class HostnameValidatorTestextends ConstraintValidatorTestCase
22+
{
23+
protectedfunctioncreateValidator()
24+
{
25+
returnnewHostnameValidator();
26+
}
27+
28+
publicfunctiontestNullIsValid()
29+
{
30+
$this->validator->validate(null,newHostname());
31+
32+
$this->assertNoViolation();
33+
}
34+
35+
publicfunctiontestEmptyStringIsValid()
36+
{
37+
$this->validator->validate('',newHostname());
38+
39+
$this->assertNoViolation();
40+
}
41+
42+
/**
43+
* @expectedException \Symfony\Component\Validator\Exception\UnexpectedValueException
44+
*/
45+
publicfunctiontestExpectsStringCompatibleType()
46+
{
47+
$this->validator->validate(new \stdClass(),newHostname());
48+
}
49+
50+
/**
51+
* @dataProvider getValidTldDomains
52+
*/
53+
publicfunctiontestValidTldDomainsPassValidationIfTldRequired($domain)
54+
{
55+
$this->validator->validate($domain,newHostname());
56+
57+
$this->assertNoViolation();
58+
}
59+
60+
/**
61+
* @dataProvider getValidTldDomains
62+
*/
63+
publicfunctiontestValidTldDomainsPassValidationIfTldNotRequired($domain)
64+
{
65+
$this->validator->validate($domain,newHostname(['requireTld' =>false]));
66+
67+
$this->assertNoViolation();
68+
}
69+
70+
publicfunctiongetValidTldDomains()
71+
{
72+
return [
73+
['symfony.com'],
74+
['example.co.uk'],
75+
['example.fr'],
76+
['example.com'],
77+
['xn--diseolatinoamericano-66b.com'],
78+
['xn--ggle-0nda.com'],
79+
['www.xn--simulateur-prt-2kb.fr'],
80+
[sprintf('%s.com',str_repeat('a',20))],
81+
];
82+
}
83+
84+
/**
85+
* @dataProvider getInvalidDomains
86+
*/
87+
publicfunctiontestInvalidDomainsRaiseViolationIfTldRequired($domain)
88+
{
89+
$this->validator->validate($domain,newHostname([
90+
'message' =>'myMessage',
91+
]));
92+
93+
$this->buildViolation('myMessage')
94+
->setParameter('{{ value }}','"'.$domain.'"')
95+
->setCode(Hostname::INVALID_HOSTNAME_ERROR)
96+
->assertRaised();
97+
}
98+
99+
/**
100+
* @dataProvider getInvalidDomains
101+
*/
102+
publicfunctiontestInvalidDomainsRaiseViolationIfTldNotRequired($domain)
103+
{
104+
$this->validator->validate($domain,newHostname([
105+
'message' =>'myMessage',
106+
'requireTld' =>false,
107+
]));
108+
109+
$this->buildViolation('myMessage')
110+
->setParameter('{{ value }}','"'.$domain.'"')
111+
->setCode(Hostname::INVALID_HOSTNAME_ERROR)
112+
->assertRaised();
113+
}
114+
115+
publicfunctiongetInvalidDomains()
116+
{
117+
return [
118+
['acme..com'],
119+
['qq--.com'],
120+
['-example.com'],
121+
['example-.com'],
122+
[sprintf('%s.com',str_repeat('a',300))],
123+
];
124+
}
125+
126+
/**
127+
* @dataProvider getReservedDomains
128+
*/
129+
publicfunctiontestReservedDomainsPassValidationIfTldNotRequired($domain)
130+
{
131+
$this->validator->validate($domain,newHostname(['requireTld' =>false]));
132+
133+
$this->assertNoViolation();
134+
}
135+
136+
/**
137+
* @dataProvider getReservedDomains
138+
*/
139+
publicfunctiontestReservedDomainsRaiseViolationIfTldRequired($domain)
140+
{
141+
$this->validator->validate($domain,newHostname([
142+
'message' =>'myMessage',
143+
'requireTld' =>true,
144+
]));
145+
146+
$this->buildViolation('myMessage')
147+
->setParameter('{{ value }}','"'.$domain.'"')
148+
->setCode(Hostname::INVALID_HOSTNAME_ERROR)
149+
->assertRaised();
150+
}
151+
152+
publicfunctiongetReservedDomains()
153+
{
154+
return [
155+
['example'],
156+
['foo.example'],
157+
['invalid'],
158+
['bar.invalid'],
159+
['localhost'],
160+
['lol.localhost'],
161+
['test'],
162+
['abc.test'],
163+
];
164+
}
165+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp