Skip to content

Commit d519b9f

Browse files
authored
Move JSON & Uuid validation out of StringTypeNarrower (#1958)
1 parent 787a8c4 commit d519b9f

File tree

8 files changed

+44
-50
lines changed

8 files changed

+44
-50
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0",
4141
"symfony/console": "^5.4 || ^6.4 || ^7.0",
4242
"symfony/http-foundation": "~5.4.0 || ~6.4.0 || ~7",
43+
"symfony/polyfill-php83": "^1.33",
4344
"symfony/string": "^5.4 || ^6.4 || ^7.0",
4445
"symfony/uid": "^6.3 || ^7.0",
4546
"webmozart/glob": "^3.0 || ^4.0"

composer.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib/types/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"types"
88
],
99
"require": {
10-
"php": "~8.2.0 || ~8.3.0 || ~8.4.0"
10+
"php": "~8.2.0 || ~8.3.0 || ~8.4.0",
11+
"symfony/polyfill-php83": "^1.33"
1112
},
1213
"config": {
1314
"optimize-autoloader": true,

src/lib/types/src/Flow/Types/Type/Logical/JsonType.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use function Flow\Types\DSL\type_json;
88
use Flow\Types\Exception\{CastingException, InvalidTypeException};
99
use Flow\Types\Type;
10-
use Flow\Types\Type\Native\String\StringTypeNarrower;
1110

1211
/**
1312
* @implements Type<string>
@@ -46,7 +45,22 @@ public function isValid(mixed $value) : bool
4645
return false;
4746
}
4847

49-
return (new StringTypeNarrower())->narrow($value) instanceof self;
48+
if ($value === '') {
49+
return false;
50+
}
51+
52+
if ('{' !== $value[0] && '[' !== $value[0]) {
53+
return false;
54+
}
55+
56+
if (
57+
!(\str_starts_with($value, '{') && \str_ends_with($value, '}'))
58+
&& !(\str_starts_with($value, '[') && \str_ends_with($value, ']'))
59+
) {
60+
return false;
61+
}
62+
63+
return \json_validate($value);
5064
}
5165

5266
public function normalize() : array

src/lib/types/src/Flow/Types/Type/Logical/UuidType.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,8 @@ public function cast(mixed $value) : mixed
4949

5050
public function isValid(mixed $value) : bool
5151
{
52-
if (\is_object($value)) {
53-
if ($value instanceof Uuid) {
54-
return true;
55-
}
52+
if ($value instanceof Uuid) {
53+
return true;
5654
}
5755

5856
return false;

src/lib/types/src/Flow/Types/Type/Native/String/StringTypeNarrower.php

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function narrow(mixed $value) : Type
3333
return type_string();
3434
}
3535

36-
$this->setString($value);
36+
$this->string = \trim($value);
3737

3838
if ($this->isNull()) {
3939
return type_null();
@@ -207,30 +207,7 @@ private function isInteger() : bool
207207

208208
private function isJson() : bool
209209
{
210-
if ($this->string === '') {
211-
return false;
212-
}
213-
214-
if ('{' !== $this->string[0] && '[' !== $this->string[0]) {
215-
return false;
216-
}
217-
218-
if (\function_exists('json_validate')) {
219-
return \json_validate($this->string);
220-
}
221-
222-
if (
223-
(!\str_starts_with($this->string, '{') || !\str_ends_with($this->string, '}'))
224-
&& (!\str_starts_with($this->string, '[') || !\str_ends_with($this->string, ']'))
225-
) {
226-
return false;
227-
}
228-
229-
try {
230-
return \is_array(\json_decode($this->string, true, flags: \JSON_THROW_ON_ERROR));
231-
} catch (\Exception) {
232-
return false;
233-
}
210+
return type_json()->isValid($this->string);
234211
}
235212

236213
private function isNull() : bool
@@ -263,15 +240,7 @@ private function isTimeZone() : bool
263240

264241
private function isUuid() : bool
265242
{
266-
if ($this->string === '') {
267-
return false;
268-
}
269-
270-
if (\strlen($this->string) !== 36) {
271-
return false;
272-
}
273-
274-
return 0 !== \preg_match(Uuid::UUID_REGEXP, $this->string);
243+
return Uuid::isValid($this->string);
275244
}
276245

277246
private function isXML() : bool
@@ -302,9 +271,4 @@ private function isXML() : bool
302271

303272
return false;
304273
}
305-
306-
private function setString(string $string) : void
307-
{
308-
$this->string = \trim($string);
309-
}
310274
}

src/lib/types/src/Flow/Types/Value/Uuid.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* This regexp is a port of the Uuid library,
1414
* which is copyright Ben Ramsey, @see https://github.com/ramsey/uuid.
1515
*/
16-
public const UUID_REGEXP = '/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/ms';
16+
private const UUID_REGEXP = '/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/ms';
1717

1818
private string $value;
1919

@@ -28,11 +28,13 @@ public function __construct(string|UuidInterface|\Symfony\Component\Uid\Uuid $va
2828
$this->value = (string) \Ramsey\Uuid\Uuid::fromString($value);
2929
} elseif (\class_exists(\Symfony\Component\Uid\Uuid::class)) {
3030
$this->value = \Symfony\Component\Uid\Uuid::fromString($value)->toRfc4122();
31+
} elseif (self::isValid($value)) {
32+
$this->value = $value;
3133
} else {
3234
throw new RuntimeException("\Ramsey\Uuid\Uuid nor \Symfony\Component\Uid\Uuid class not found, please add 'ramsey/uuid' or 'symfony/uid' as a dependency to the project first.");
3335
}
3436
} catch (\InvalidArgumentException $e) {
35-
throw new InvalidArgumentException("Invalid UUID: '{$value}'", 0, $e);
37+
throw new InvalidArgumentException("Invalid UUID: '{$value}'", $e->getCode(), $e);
3638
}
3739
} elseif ($value instanceof UuidInterface) {
3840
$this->value = $value->toString();
@@ -46,6 +48,15 @@ public static function fromString(string $value) : self
4648
return new self($value);
4749
}
4850

51+
public static function isValid(string $value) : bool
52+
{
53+
if (\strlen($value) !== 36) {
54+
return false;
55+
}
56+
57+
return 1 === \preg_match(self::UUID_REGEXP, $value);
58+
}
59+
4960
public function __toString() : string
5061
{
5162
return $this->toString();

src/lib/types/tests/Flow/Types/Tests/Unit/Value/UuidTest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ public function test_construct_with_invalid_string_uuid_throws_exception() : voi
1818
new Uuid('invalid-uuid-string');
1919
}
2020

21+
public function test_construct_with_invalid_uuid_throws_exception() : void
22+
{
23+
$this->expectException(InvalidArgumentException::class);
24+
new Uuid('********-****-****-****************');
25+
}
26+
2127
public function test_construct_with_ramsey_uuid_instance() : void
2228
{
2329
$ramseyUuid = RamseyUuid::uuid4();
@@ -47,7 +53,6 @@ public function test_from_string_creates_instance() : void
4753
$uuidString = '123e4567-e89b-12d3-a456-426614174000';
4854
$uuid = Uuid::fromString($uuidString);
4955

50-
self::assertInstanceOf(Uuid::class, $uuid);
5156
self::assertSame($uuidString, $uuid->toString());
5257
}
5358

0 commit comments

Comments
 (0)