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

Commit6233382

Browse files
raffaelecarellefabpot
authored andcommitted
[Validator] AddSlug constraint
1 parente23a0d2 commit6233382

File tree

5 files changed

+242
-0
lines changed

5 files changed

+242
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Add support for ratio checks for SVG files to the`Image` constraint
8+
* Add the`Slug` constraint
89

910
7.2
1011
---
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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+
* Validates that a value is a valid slug.
18+
*
19+
* @author Raffaele Carelle <raffaele.carelle@gmail.com>
20+
*/
21+
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
22+
class Slugextends Constraint
23+
{
24+
publicconstNOT_SLUG_ERROR ='14e6df1e-c8ab-4395-b6ce-04b132a3765e';
25+
26+
publicstring$message ='This value is not a valid slug.';
27+
publicstring$regex ='/^[a-z0-9]+(?:-[a-z0-9]+)*$/';
28+
29+
publicfunction__construct(
30+
?array$options =null,
31+
?string$regex =null,
32+
?string$message =null,
33+
?array$groups =null,
34+
mixed$payload =null,
35+
) {
36+
parent::__construct($options,$groups,$payload);
37+
38+
$this->message =$message ??$this->message;
39+
$this->regex =$regex ??$this->regex;
40+
}
41+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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 Raffaele Carelle <raffaele.carelle@gmail.com>
21+
*/
22+
class SlugValidatorextends ConstraintValidator
23+
{
24+
publicfunctionvalidate(mixed$value,Constraint$constraint):void
25+
{
26+
if (!$constraintinstanceof Slug) {
27+
thrownewUnexpectedTypeException($constraint, Slug::class);
28+
}
29+
30+
if (null ===$value ||'' ===$value) {
31+
return;
32+
}
33+
34+
if (!\is_scalar($value) && !$valueinstanceof \Stringable) {
35+
thrownewUnexpectedValueException($value,'string');
36+
}
37+
38+
$value = (string)$value;
39+
40+
if (0 ===preg_match($constraint->regex,$value)) {
41+
$this->context->buildViolation($constraint->message)
42+
->setParameter('{{ value }}',$this->formatValue($value))
43+
->setCode(Slug::NOT_SLUG_ERROR)
44+
->addViolation();
45+
}
46+
}
47+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
usePHPUnit\Framework\TestCase;
15+
useSymfony\Component\Validator\Constraints\Slug;
16+
useSymfony\Component\Validator\Mapping\ClassMetadata;
17+
useSymfony\Component\Validator\Mapping\Loader\AttributeLoader;
18+
19+
class SlugTestextends TestCase
20+
{
21+
publicfunctiontestAttributes()
22+
{
23+
$metadata =newClassMetadata(SlugDummy::class);
24+
$loader =newAttributeLoader();
25+
self::assertTrue($loader->loadClassMetadata($metadata));
26+
27+
[$bConstraint] =$metadata->properties['b']->getConstraints();
28+
self::assertSame('myMessage',$bConstraint->message);
29+
self::assertSame(['Default','SlugDummy'],$bConstraint->groups);
30+
31+
[$cConstraint] =$metadata->properties['c']->getConstraints();
32+
self::assertSame(['my_group'],$cConstraint->groups);
33+
self::assertSame('some attached data',$cConstraint->payload);
34+
}
35+
}
36+
37+
class SlugDummy
38+
{
39+
#[Slug]
40+
private$a;
41+
42+
#[Slug(message:'myMessage')]
43+
private$b;
44+
45+
#[Slug(groups: ['my_group'], payload:'some attached data')]
46+
private$c;
47+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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\Slug;
15+
useSymfony\Component\Validator\Constraints\SlugValidator;
16+
useSymfony\Component\Validator\Exception\UnexpectedValueException;
17+
useSymfony\Component\Validator\Test\ConstraintValidatorTestCase;
18+
19+
class SlugValidatorTestextends ConstraintValidatorTestCase
20+
{
21+
protectedfunctioncreateValidator():SlugValidator
22+
{
23+
returnnewSlugValidator();
24+
}
25+
26+
publicfunctiontestNullIsValid()
27+
{
28+
$this->validator->validate(null,newSlug());
29+
30+
$this->assertNoViolation();
31+
}
32+
33+
publicfunctiontestEmptyStringIsValid()
34+
{
35+
$this->validator->validate('',newSlug());
36+
37+
$this->assertNoViolation();
38+
}
39+
40+
publicfunctiontestExpectsStringCompatibleType()
41+
{
42+
$this->expectException(UnexpectedValueException::class);
43+
$this->validator->validate(new \stdClass(),newSlug());
44+
}
45+
46+
/**
47+
* @testWith ["test-slug"]
48+
* ["slug-123-test"]
49+
* ["slug"]
50+
*/
51+
publicfunctiontestValidSlugs($slug)
52+
{
53+
$this->validator->validate($slug,newSlug());
54+
55+
$this->assertNoViolation();
56+
}
57+
58+
/**
59+
* @testWith ["NotASlug"]
60+
* ["Not a slug"]
61+
* ["not-á-slug"]
62+
* ["not-@-slug"]
63+
*/
64+
publicfunctiontestInvalidSlugs($slug)
65+
{
66+
$constraint =newSlug([
67+
'message' =>'myMessage',
68+
]);
69+
70+
$this->validator->validate($slug,$constraint);
71+
72+
$this->buildViolation('myMessage')
73+
->setParameter('{{ value }}','"'.$slug.'"')
74+
->setCode(Slug::NOT_SLUG_ERROR)
75+
->assertRaised();
76+
}
77+
78+
/**
79+
* @testWith ["test-slug", true]
80+
* ["slug-123-test", true]
81+
*/
82+
publicfunctiontestCustomRegexInvalidSlugs($slug)
83+
{
84+
$constraint =newSlug(regex:'/^[a-z0-9]+$/i');
85+
86+
$this->validator->validate($slug,$constraint);
87+
88+
$this->buildViolation($constraint->message)
89+
->setParameter('{{ value }}','"'.$slug.'"')
90+
->setCode(Slug::NOT_SLUG_ERROR)
91+
->assertRaised();
92+
}
93+
94+
/**
95+
* @testWith ["slug"]
96+
* @testWith ["test1234"]
97+
*/
98+
publicfunctiontestCustomRegexValidSlugs($slug)
99+
{
100+
$constraint =newSlug(regex:'/^[a-z0-9]+$/i');
101+
102+
$this->validator->validate($slug,$constraint);
103+
104+
$this->assertNoViolation();
105+
}
106+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp