diff --git a/src/Illuminate/Support/Str.php b/src/Illuminate/Support/Str.php index ae75a05c16b2..0d23c49597e1 100644 --- a/src/Illuminate/Support/Str.php +++ b/src/Illuminate/Support/Str.php @@ -14,7 +14,15 @@ use Ramsey\Uuid\Generator\CombGenerator; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidFactory; +use Symfony\Component\Uid\NilUuid; use Symfony\Component\Uid\Ulid; +use Symfony\Component\Uid\UuidV1; +use Symfony\Component\Uid\UuidV3; +use Symfony\Component\Uid\UuidV4; +use Symfony\Component\Uid\UuidV5; +use Symfony\Component\Uid\UuidV6; +use Symfony\Component\Uid\UuidV7; +use Symfony\Component\Uid\UuidV8; use Throwable; use Traversable; use voku\helper\ASCII; @@ -595,15 +603,31 @@ public static function isUrl($value, array $protocols = []) * Determine if a given value is a valid UUID. * * @param mixed $value + * @param int<-1, 8>|null $version * @return bool */ - public static function isUuid($value) + public static function isUuid($value, $version = null) { if (! is_string($value)) { return false; } - return preg_match('/^[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}$/D', $value) > 0; + if ($version === null) { + return preg_match('/^[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}$/D', $value) > 0; + } + + return match ($version) { + -1, 0 => NilUuid::isValid($value), + 1 => UuidV1::isValid($value), + // 2 => UuidV2::isValid($value), // Symfony/uid doesn't implement version 2 + 3 => UuidV3::isValid($value), + 4 => UuidV4::isValid($value), + 5 => UuidV5::isValid($value), + 6 => UuidV6::isValid($value), + 7 => UuidV7::isValid($value), + 8 => UuidV8::isValid($value), + default => false, + }; } /** diff --git a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php index 901fcf18ab53..e26c5300797f 100644 --- a/src/Illuminate/Validation/Concerns/ValidatesAttributes.php +++ b/src/Illuminate/Validation/Concerns/ValidatesAttributes.php @@ -2550,11 +2550,12 @@ public function validateUlid($attribute, $value) * * @param string $attribute * @param mixed $value + * @param array> $parameters * @return bool */ - public function validateUuid($attribute, $value) + public function validateUuid($attribute, $value, $parameters) { - return Str::isUuid($value); + return Str::isUuid($value, $parameters !== null && count($parameters) === 1 ? (int) $parameters[0] : null); } /** diff --git a/tests/Support/SupportStrTest.php b/tests/Support/SupportStrTest.php index 4508bf5b5e2f..fed5d2c57c4d 100755 --- a/tests/Support/SupportStrTest.php +++ b/tests/Support/SupportStrTest.php @@ -597,6 +597,12 @@ public function testIsUuidWithInvalidUuid($uuid) $this->assertFalse(Str::isUuid($uuid)); } + #[DataProvider('uuidVersionList')] + public function testIsUuidWithVersion($uuid, $version, $passes) + { + $this->assertSame(Str::isUuid($uuid, $version), $passes); + } + public function testIsJson() { $this->assertTrue(Str::isJson('1')); @@ -1306,6 +1312,24 @@ public static function invalidUuidList() ]; } + public static function uuidVersionList() + { + return [ + ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', null, true], + ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 1, false], + ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 4, true], + ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 42, false], + ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', null, true], + ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 1, true], + ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 4, false], + ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 42, false], + ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', null, false], + ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 1, false], + ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 4, false], + ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 42, false], + ]; + } + public static function strContainsProvider() { return [ diff --git a/tests/Validation/ValidationValidatorTest.php b/tests/Validation/ValidationValidatorTest.php index 5ad5fc600a96..99814b4d481c 100755 --- a/tests/Validation/ValidationValidatorTest.php +++ b/tests/Validation/ValidationValidatorTest.php @@ -8445,6 +8445,14 @@ public function testValidateWithInvalidUuid($uuid) $this->assertFalse($v->passes()); } + #[DataProvider('uuidVersionList')] + public function testValidateWithUuidWithVersionConstraint($uuid, $rule, $passes) + { + $trans = $this->getIlluminateArrayTranslator(); + $v = new Validator($trans, ['foo' => $uuid], ['foo' => $rule]); + $this->assertSame($v->passes(), $passes); + } + public static function validUuidList() { return [ @@ -8477,6 +8485,24 @@ public static function invalidUuidList() ]; } + public static function uuidVersionList() + { + return [ + ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 'uuid', true], + ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 'uuid:1', false], + ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 'uuid:4', true], + ['a0a2a2d2-0b87-4a18-83f2-2529882be2de', 'uuid:42', false], + ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 'uuid', true], + ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 'uuid:1', true], + ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 'uuid:4', false], + ['145a1e72-d11d-11e8-a8d5-f2801f1b9fd1', 'uuid:42', false], + ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 'uuid', false], + ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 'uuid:1', false], + ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 'uuid:4', false], + ['zf6f8cb0-c57d-11e1-9b21-0800200c9a66', 'uuid:42', false], + ]; + } + public function testValidateWithValidAscii() { $trans = $this->getIlluminateArrayTranslator();