8000 [Validator] Add support for RFC4122 format in the `Ulid` constraint · symfony/symfony@9382d71 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9382d71

Browse files
[Validator] Add support for RFC4122 format in the Ulid constraint
1 parent 212f5b7 commit 9382d71

File tree

4 files changed

+56
-4
lines changed

4 files changed

+56
-4
lines changed

src/Symfony/Component/Validator/Constraints/Ulid.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,21 @@ class Ulid extends Constraint
2626
{
2727
public const TOO_SHORT_ERROR = '7b44804e-37d5-4df4-9bdd-b738d4a45bb4';
2828
public const TOO_LONG_ERROR = '9608249f-6da1-4d53-889e-9864b58c4d37';
29-
public const INVALID_CHARACTERS_ERROR = 'e4155739-5135-4258-9c81-ae7b44b5311e';
3029
public const TOO_LARGE_ERROR = 'df8cfb9a-ce6d-4a69-ae5a-eea7ab6f278b';
30+
public const INVALID_CHARACTERS_ERROR = 'e4155739-5135-4258-9c81-ae7b44b5311e';
31+
public const INVALID_FORMAT_ERROR = '34d5cdd7-5aac-4ba0-b9a2-b45e0bab3e2e';
3132

3233
protected const ERROR_NAMES = [
3334
self::TOO_SHORT_ERROR => 'TOO_SHORT_ERROR',
3435
self::TOO_LONG_ERROR => 'TOO_LONG_ERROR',
35-
self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR',
3636
self::TOO_LARGE_ERROR => 'TOO_LARGE_ERROR',
37+
self::INVALID_CHARACTERS_ERROR => 'INVALID_CHARACTERS_ERROR',
38+
self::INVALID_FORMAT_ERROR => 'INVALID_FORMAT_ERROR',
3739
];
3840

3941
public const FORMAT_BASE_32 = 'base32';
4042
public const FORMAT_BASE_58 = 'base58';
43+
public const FORMAT_RFC_4122 = 'rfc4122';
4144

4245
public string $message = 'This is not a valid ULID.';
4346
public string $format = self::FORMAT_BASE_32;
@@ -59,7 +62,7 @@ public function __construct(
5962
$this->message = $message ?? $this->message;
6063
$this->format = $format ?? $this->format;
6164

62-
if (!\in_array($this->format, [self::FORMAT_BASE_32, self::FORMAT_BASE_58], true)) {
65+
if (!\in_array($this->format, [self::FORMAT_BASE_32, self::FORMAT_BASE_58, self::FORMAT_RFC_4122], true)) {
6366
throw new ConstraintDefinitionException(\sprintf('The "%s" validation format is not supported.', $format));
6467
}
6568
}

src/Symfony/Component/Validator/Constraints/UlidValidator.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public function validate(mixed $value, Constraint $constraint): void
4343
[$requiredLength, $requiredCharset] = match ($constraint->format) {
4444
Ulid::FORMAT_BASE_32 => [26, '0123456789ABCDEFGHJKMNPQRSTVWXYZabcdefghjkmnpqrstvwxyz'],
4545
Ulid::FORMAT_BASE_58 => [22, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'],
46+
Ulid::FORMAT_RFC_4122 => [36, '0123456789ABCDEFabcdef-'],
4647
};
4748

4849
if ($requiredLength !== \strlen($value)) {
@@ -81,6 +82,16 @@ public function validate(mixed $value, Constraint $constraint): void
8182
->setCode(Ulid::TOO_LARGE_ERROR)
8283
->addViolation();
8384
}
85+
} elseif (Ulid::FORMAT_RFC_4122 === $constraint->format) {
86+
if (!preg_match('/^[^-]{8}-[^-]{4}-[^-]{4}-[^-]{4}-[^-]{12}$/', $value)) {
87+
$this->context->buildViolation($constraint->message)
88+
->setParameters([
89+
'{{ value }}' => $this->formatValue($value),
90+
'{{ format }}' => $constraint->format,
91+
])
92+
->setCode(Ulid::INVALID_FORMAT_ERROR)
93+
->addViolation();
94+
}
8495
}
8596
}
8697
}

src/Symfony/Component/Validator/Tests/Constraints/UlidTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public function testAttributes()
2828
[$bConstraint] = $metadata->properties['b']->getConstraints();
2929
self::assertSame('myMessage', $bConstraint->message);
3030
self::assertSame(['Default', 'UlidDummy'], $bConstraint->groups);
31+
self::assertSame(Ulid::FORMAT_BASE_58, $bConstraint->format);
3132

3233
[$cConstraint] = $metadata->properties['c']->getConstraints();
3334
self::assertSame(['my_group'], $cConstraint->groups);
@@ -48,7 +49,7 @@ class UlidDummy
4849
#[Ulid]
4950
private $a;
5051

51-
#[Ulid(message: 'myMessage')]
52+
#[Ulid(message: 'myMessage', format: Ulid::FORMAT_BASE_58)]
5253
private $b;
5354

5455
#[Ulid(groups: ['my_group'], payload: 'some attached data')]

src/Symfony/Component/Validator/Tests/Constraints/UlidValidatorTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ public function testValidUlidAsBase58()
6060
$this->assertNoViolation();
6161
}
6262

63+
public function testValidUlidAsRfc4122()
64+
{
65+
$this->validator->validate('01912bf3-feff-fa6c-00f2-90d2f2e00564', new Ulid(format: Ulid::FORMAT_RFC_4122));
66+
67+
$this->assertNoViolation();
68+
}
69+
6370
/**
6471
* @dataProvider getInvalidUlids
6572
*/
@@ -119,6 +126,36 @@ public static function getInvalidBase58Ulids(): array
119126
];
120127
}
121128

129+
/**
130+
* @dataProvider getInvalidRfc4122Ulids
131+
*/
132+
public function testInvalidInvalid4122Ulid(string $ulid, string $code)
133+
{
134+
$constraint = new Ulid(message: 'testMessage', format: Ulid::FORMAT_RFC_4122);
135+
136+
$this->validator->validate($ulid, $constraint);
137+
138+
$this->buildViolation('testMessage')
139+
->setParameters([
140+
'{{ value }}' => '"'.$ulid.'"',
141+
'{{ format }}' => Ulid::FORMAT_RFC_4122,
142+
])
143+
->setCode($code)
144+
->assertRaised();
145+
}
146+
147+
public static function getInvalidRfc4122Ulids(): array
148+
{
149+
return [
150+
['01912bf3-f5b7-e55d', Ulid::TOO_SHORT_ERROR],
151+
['01912bf3-f5b7-e55d-d21f-5ef032cd8e29999999', Ulid::TOO_LONG_ERROR],
152+
['01912bf3-f5b7-e55d-d21f-5ef032cd8eZZ', Ulid::INVALID_CHARACTERS_ERROR],
153+
['not-even-ulid-like', Ulid::TOO_SHORT_ERROR],
154+
['01912bf30feff0fa6c000f2090d2f2e00564', Ulid::INVALID_FORMAT_ERROR],
155+
['019-2bf3-feff-fa6c-00f2-90d2f2e00564', Ulid::INVALID_FORMAT_ERROR],
156+
];
157+
}
158+
122159
public function testInvalidUlidNamed()
123160
{
124161
$constraint = new Ulid(message: 'testMessage');

0 commit comments

Comments
 (0)
0