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

Commitd39da0d

Browse files
javiereguiluzfabpot
authored andcommitted
[Validator] Add arequireTld option toUrl constraint
1 parent78c6ceb commitd39da0d

File tree

5 files changed

+72
-0
lines changed

5 files changed

+72
-0
lines changed

‎src/Symfony/Component/Validator/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
* Possibility to use all`Ip` constraint versions for`Cidr` constraint
1111
* Add`list` and`associative_array` types to`Type` constraint
1212
* Add the`Charset` constraint
13+
* Add the`requireTld` option to the`Url` constraint
1314

1415
7.0
1516
---

‎src/Symfony/Component/Validator/Constraints/Url.php‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,18 @@
2323
class Urlextends Constraint
2424
{
2525
publicconstINVALID_URL_ERROR ='57c2f299-1154-4870-89bb-ef3b1f5ad229';
26+
publicconstMISSING_TLD_ERROR ='8a5d387f-0716-46b4-844b-67367faf435a';
2627

2728
protectedconstERROR_NAMES = [
2829
self::INVALID_URL_ERROR =>'INVALID_URL_ERROR',
30+
self::MISSING_TLD_ERROR =>'MISSING_TLD_ERROR',
2931
];
3032

3133
publicstring$message ='This value is not a valid URL.';
34+
publicstring$tldMessage ='This URL does not contain a TLD.';
3235
publicarray$protocols = ['http','https'];
3336
publicbool$relativeProtocol =false;
37+
publicbool$requireTld =false;
3438
/** @var callable|null */
3539
public$normalizer;
3640

@@ -39,6 +43,7 @@ class Url extends Constraint
3943
* @param string[]|null $protocols The protocols considered to be valid for the URL (e.g. http, https, ftp, etc.) (defaults to ['http', 'https']
4044
* @param bool|null $relativeProtocol Whether to accept URL without the protocol (i.e. //example.com) (defaults to false)
4145
* @param string[]|null $groups
46+
* @param bool|null $requireTld Whether to require the URL to include a top-level domain (defaults to false)
4247
*/
4348
publicfunction__construct(
4449
?array$options =null,
@@ -48,13 +53,15 @@ public function __construct(
4853
?callable$normalizer =null,
4954
?array$groups =null,
5055
mixed$payload =null,
56+
?bool$requireTld =null,
5157
) {
5258
parent::__construct($options,$groups,$payload);
5359

5460
$this->message =$message ??$this->message;
5561
$this->protocols =$protocols ??$this->protocols;
5662
$this->relativeProtocol =$relativeProtocol ??$this->relativeProtocol;
5763
$this->normalizer =$normalizer ??$this->normalizer;
64+
$this->requireTld =$requireTld ??$this->requireTld;
5865

5966
if (null !==$this->normalizer && !\is_callable($this->normalizer)) {
6067
thrownewInvalidArgumentException(sprintf('The "normalizer" option must be a valid callable ("%s" given).',get_debug_type($this->normalizer)));

‎src/Symfony/Component/Validator/Constraints/UrlValidator.php‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,18 @@ public function validate(mixed $value, Constraint $constraint): void
7979

8080
return;
8181
}
82+
83+
if ($constraint->requireTld) {
84+
$urlHost =parse_url($value, \PHP_URL_HOST);
85+
// the host of URLs with a TLD must include at least a '.' (but it can't be an IP address like '127.0.0.1')
86+
if (!str_contains($urlHost,'.') ||filter_var($urlHost, \FILTER_VALIDATE_IP)) {
87+
$this->context->buildViolation($constraint->tldMessage)
88+
->setParameter('{{ value }}',$this->formatValue($value))
89+
->setCode(Url::MISSING_TLD_ERROR)
90+
->addViolation();
91+
92+
return;
93+
}
94+
}
8295
}
8396
}

‎src/Symfony/Component/Validator/Tests/Constraints/UrlTest.php‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,26 @@ public function testAttributes()
5252
self::assertSame(['http','https'],$aConstraint->protocols);
5353
self::assertFalse($aConstraint->relativeProtocol);
5454
self::assertNull($aConstraint->normalizer);
55+
self::assertFalse($aConstraint->requireTld);
5556

5657
[$bConstraint] =$metadata->properties['b']->getConstraints();
5758
self::assertSame(['ftp','gopher'],$bConstraint->protocols);
5859
self::assertSame('trim',$bConstraint->normalizer);
5960
self::assertSame('myMessage',$bConstraint->message);
6061
self::assertSame(['Default','UrlDummy'],$bConstraint->groups);
62+
self::assertFalse($bConstraint->requireTld);
6163

6264
[$cConstraint] =$metadata->properties['c']->getConstraints();
6365
self::assertTrue($cConstraint->relativeProtocol);
6466
self::assertSame(['my_group'],$cConstraint->groups);
6567
self::assertSame('some attached data',$cConstraint->payload);
68+
self::assertFalse($cConstraint->requireTld);
69+
70+
[$dConstraint] =$metadata->properties['d']->getConstraints();
71+
self::assertSame(['http','https'],$aConstraint->protocols);
72+
self::assertFalse($aConstraint->relativeProtocol);
73+
self::assertNull($aConstraint->normalizer);
74+
self::assertTrue($dConstraint->requireTld);
6675
}
6776
}
6877

@@ -76,4 +85,7 @@ class UrlDummy
7685

7786
#[Url(relativeProtocol:true, groups: ['my_group'], payload:'some attached data')]
7887
private$c;
88+
89+
#[Url(requireTld:true)]
90+
private$d;
7991
}

‎src/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,45 @@ public static function getValidCustomUrls()
311311
['git://[::1]/'],
312312
];
313313
}
314+
315+
/**
316+
* @dataProvider getUrlsForRequiredTld
317+
*/
318+
publicfunctiontestRequiredTld(string$url,bool$requireTld,bool$isValid)
319+
{
320+
$constraint =newUrl([
321+
'requireTld' =>$requireTld,
322+
]);
323+
324+
$this->validator->validate($url,$constraint);
325+
326+
if ($isValid) {
327+
$this->assertNoViolation();
328+
}else {
329+
$this->buildViolation($constraint->tldMessage)
330+
->setParameter('{{ value }}','"'.$url.'"')
331+
->setCode(Url::MISSING_TLD_ERROR)
332+
->assertRaised();
333+
}
334+
}
335+
336+
publicstaticfunctiongetUrlsForRequiredTld():iterable
337+
{
338+
yield ['https://aaa',true,false];
339+
yield ['https://aaa',false,true];
340+
yield ['https://localhost',true,false];
341+
yield ['https://localhost',false,true];
342+
yield ['http://127.0.0.1',false,true];
343+
yield ['http://127.0.0.1',true,false];
344+
yield ['http://user.pass@local',false,true];
345+
yield ['http://user.pass@local',true,false];
346+
yield ['https://example.com',true,true];
347+
yield ['https://example.com',false,true];
348+
yield ['http://foo/bar.png',false,true];
349+
yield ['http://foo/bar.png',true,false];
350+
yield ['https://example.com.org',true,true];
351+
yield ['https://example.com.org',false,true];
352+
}
314353
}
315354

316355
class EmailProvider

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp