Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e0e3413

Browse files
committed
[Uid] Add the UidValueResolver argument value resolver
1 parent b2e7fcd commit e0e3413

File tree

18 files changed

+544
-1
lines changed

18 files changed

+544
-1
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,6 +2038,15 @@ private function addUidSection(ArrayNodeDefinition $rootNode, callable $enableIf
20382038
->scalarNode('time_based_uuid_node')
20392039
->cannotBeEmpty()
20402040
->end()
2041+
->arrayNode('argument_value_resolver')
2042+
->canBeEnabled()
2043+
->children()
2044+
->enumNode('default_format')
2045+
->values(['canonical', 'base58', 'base32', 'rfc4122', 'any'])
2046+
->defaultValue('canonical')
2047+
->end()
2048+
->end()
2049+
->end()
20412050
->end()
20422051
->end()
20432052
->end()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2545,6 +2545,17 @@ private function registerUidConfiguration(array $config, ContainerBuilder $conta
25452545
$container->getDefinition('name_based_uuid.factory')
25462546
->setArguments([$config['name_based_uuid_namespace']]);
25472547
}
2548+
2549+
if (!$config['argument_value_resolver']['enabled']) {
2550+
$container->removeDefinition('argument_resolver.uid');
2551+
2552+
return;
2553+
}
2554+
2555+
$container->getDefinition('argument_resolver.uid')
2556+
->setArguments([
2557+
$config['argument_value_resolver']['default_format'],
2558+
]);
25482559
}
25492560

25502561
private function resolveTrustedHeaders(array $headers): int

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,9 @@
735735
</xsd:complexType>
736736

737737
<xsd:complexType name="uid">
738+
<xsd:sequence>
739+
<xsd:element name="argument_value_resolver" type="uid_argument_value_resolver" minOccurs="0" />
740+
</xsd:sequence>
738741
<xsd:attribute name="enabled" type="xsd:boolean" />
739742
<xsd:attribute name="default_uuid_version" type="default_uuid_version" />
740743
<xsd:attribute name="name_based_uuid_version" type="name_based_uuid_version" />
@@ -765,6 +768,21 @@
765768
</xsd:restriction>
766769
</xsd:simpleType>
767770

771+
<xsd:complexType name="uid_argument_value_resolver">
772+
<xsd:attribute name="enabled" type="xsd:boolean" />
773+
<xsd:attribute name="default_format" type="uid_argument_value_resolver_default_format" />
774+
</xsd:complexType>
775+
776+
<xsd:simpleType name="uid_argument_value_resolver_default_format">
777+
<xsd:restriction base="xsd:string">
778+
<xsd:enumeration value="canonical" />
779+
<xsd:enumeration value="base58" />
780+
<xsd:enumeration value="base32" />
781+
<xsd:enumeration value="rfc4122" />
782+
<xsd:enumeration value="any" />
783+
</xsd:restriction>
784+
</xsd:simpleType>
785+
768786
<xsd:complexType name="notifier">
769787
<xsd:sequence>
770788
<xsd:element name="chatter-transport" type="chatter-transport" minOccurs="0" maxOccurs="unbounded" />

src/Symfony/Bundle/FrameworkBundle/Resources/config/uid.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1313

14+
use Symfony\Component\Uid\ArgumentResolver\UidValueResolver;
1415
use Symfony\Component\Uid\Factory\NameBasedUuidFactory;
1516
use Symfony\Component\Uid\Factory\RandomBasedUuidFactory;
1617
use Symfony\Component\Uid\Factory\TimeBasedUuidFactory;
@@ -37,5 +38,8 @@
3738
->set('time_based_uuid.factory', TimeBasedUuidFactory::class)
3839
->factory([service('uuid.factory'), 'timeBased'])
3940
->alias(TimeBasedUuidFactory::class, 'time_based_uuid.factory')
41+
42+
->set('argument_resolver.uid', UidValueResolver::class)
43+
->tag('controller.argument_value_resolver', ['priority' => 150]) // Higher than RequestAttributeValueResolver
4044
;
4145
};

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,10 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
580580
'default_uuid_version' => 6,
581581
'name_based_uuid_version' => 5,
582582
'time_based_uuid_version' => 6,
583+
'argument_value_resolver' => [
584+
'enabled' => false,
585+
'default_format' => 'canonical',
586+
],
583587
],
584588
'exceptions' => [],
585589
];
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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+
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller;
13+
14+
use Symfony\Component\HttpFoundation\Response;
15+
use Symfony\Component\Routing\Annotation\Route;
16+
use Symfony\Component\Uid\Attribute\Uid;
17+
use Symfony\Component\Uid\Ulid;
18+
use Symfony\Component\Uid\UuidV1;
19+
use Symfony\Component\Uid\UuidV4;
20+
use Symfony\Component\Uid\UuidV6;
21+
22+
class UidController
23+
{
24+
#[Route(path: '/no-attribute/ulid/{userId}')]
25+
public function noAttribute(Ulid $userId): Response
26+
{
27+
return new Response($userId);
28+
}
29+
30+
#[Route(path: '/no-attribute/many-uids/uuid-v6/{postId}/custom-uid/{commentId}')]
31+
public function noAttributeManyUids(UuidV6 $postId, TestCommentIdentifier $commentId): Response
32+
{
33+
return new Response($postId."\n".$commentId);
34+
}
35+
36+
#[Route(path: '/attribute/all-defaults/uuid-v6/{id}')]
37+
public function attributeAllDefaults(#[Uid] UuidV6 $id): Response
38+
{
39+
return new Response($id);
40+
}
41+
42+
#[Route(path: '/attribute/with-format/uuid-v4/{id}')]
43+
public function attributeWithFormat(#[Uid(format: Uid::FORMAT_BASE58)] UuidV4 $id): Response
44+
{
45+
return new Response($id);
46+
}
47+
48+
#[Route(path: '/attribute/many-uids/uuid-v1/post_{postId}/uuid-v6/comment_{commentId}')]
49+
public function attributeManyUids(
50+
#[Uid(format: Uid::FORMAT_CANONICAL)] UuidV1 $postId,
51+
#[Uid(format: Uid::FORMAT_BASE58)] UuidV6 $commentId,
52+
): Response {
53+
return new Response($postId."\n".$commentId);
54+
}
55+
56+
#[Route(path: '/attribute/uuid-v6/{postId}/no-attribute/uuid-v6/{commentId}')]
57+
public function noAttributeAndAttribute(
58+
#[Uid(format: Uid::FORMAT_ANY)] UuidV6 $postId,
59+
UuidV6 $commentId,
60+
): Response {
61+
return new Response($postId."\n".$commentId);
62+
}
63+
}
64+
65+
class TestCommentIdentifier extends UuidV6
66+
{
67+
}

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,7 @@ array_controller:
6060
send_email:
6161
path: /send_email
6262
defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\EmailController::indexAction }
63+
64+
uid:
65+
resource: "../../Controller/UidController.php"
66+
type: "annotation"
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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+
namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;
13+
14+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\UidController;
15+
use Symfony\Component\Uid\Ulid;
16+
use Symfony\Component\Uid\UuidV1;
17+
use Symfony\Component\Uid\UuidV4;
18+
use Symfony\Component\Uid\UuidV6;
19+
20+
class UidTest extends AbstractWebTestCase
21+
{
22+
/**
23+
* @see UidController
24+
*/
25+
public function testArgumentValueResolverConfigAllDefaults()
26+
{
27+
$client = $this->createClient(['test_case' => 'Uid', 'root_config' => 'config_all_defaults.yml']);
28+
29+
// format === canonical (default from config)
30+
// Ulid canonical = ok
31+
$client->request('GET', '/no-attribute/ulid/'.$ulid = new Ulid());
32+
$this->assertSame((string) $ulid, $client->getResponse()->getContent());
33+
// base58 !== ulid canonical
34+
$client->request('GET', '/no-attribute/ulid/'.$ulid->toBase58());
35+
$this->assertSame(404, $client->getResponse()->getStatusCode());
36+
37+
// format === canonical on both ids (default from config)
38+
// Both uuid v6 canonical = ok
39+
$client->request('GET', '/no-attribute/many-uids/uuid-v6/'.($uuidV6 = new UuidV6()).'/custom-uid/'.$uuidV6);
40+
$this->assertSame($uuidV6."\n".$uuidV6, $client->getResponse()->getContent());
41+
// First id: base32 !== uuid v6 canonical
42+
$client->request('GET', '/no-attribute/many-uids/uuid-v6/'.$uuidV6->toBase32().'/custom-uid/'.$uuidV6);
43+
$this->assertSame(404, $client->getResponse()->getStatusCode());
44+
// Second id: uuid v4 !== uuid v6
45+
$client->request('GET', '/no-attribute/many-uids/uuid-v6/'.$uuidV6.'/custom-uid/'.($uuidV4 = new UuidV4()));
46+
$this->assertSame(404, $client->getResponse()->getStatusCode());
47+
48+
// format === canonical (default from config)
49+
// Uuid v6 canonical = ok
50+
$client->request('GET', '/attribute/all-defaults/uuid-v6/'.$uuidV6 = new UuidV6());
51+
$this->assertSame((string) $uuidV6, $client->getResponse()->getContent());
52+
// base58 !== uuid v6 canonical
53+
$client->request('GET', '/attribute/all-defaults/uuid-v6/'.$uuidV6->toBase58());
54+
$this->assertSame(404, $client->getResponse()->getStatusCode());
55+
// Uuid v1 !== uuid v6
56+
$client->request('GET', '/attribute/all-defaults/uuid-v6/'.($uuidV1 = new UuidV1()));
57+
$this->assertSame(404, $client->getResponse()->getStatusCode());
58+
59+
// format === base58 (attribute)
60+
// Uuid v4 base58 = ok
61+
$client->request('GET', '/attribute/with-format/uuid-v4/'.$uuidV4->toBase58());
62+
$this->assertSame((string) $uuidV4, $client->getResponse()->getContent());
63+
// Uuid v4 canonical !== base58
64+
$client->request('GET', '/attribute/with-format/uuid-v4/'.$uuidV4);
65+
$this->assertSame(404, $client->getResponse()->getStatusCode());
66+
// Uuid v1 !== uuid v4
67+
$client->request('GET', '/attribute/with-format/uuid-v4/'.$uuidV1->toBase58());
68+
$this->assertSame(404, $client->getResponse()->getStatusCode());
69+
70+
// format === canonical on the first id (attribute), base58 on the second one (attribute)
71+
// Uuid v1 canonical + uuid v6 base58 = ok
72+
$client->request('GET', '/attribute/many-uids/uuid-v1/post_'.$uuidV1.'/uuid-v6/comment_'.$uuidV6->toBase58());
73+
$this->assertSame($uuidV1."\n".$uuidV6, $client->getResponse()->getContent());
74+
// First id: base32 !== uuid v1 canonical
75+
$client->request('GET', '/attribute/many-uids/uuid-v1/post_'.$uuidV1->toBase32().'/uuid-v6/comment_'.$uuidV6->toBase58());
76+
$this->assertSame(404, $client->getResponse()->getStatusCode());
77+
// Second id: uuidv1 !== uuidv6
78+
$client->request('GET', '/attribute/many-uids/uuid-v1/post_'.$uuidV1.'/uuid-v6/comment_'.$uuidV1);
79+
$this->assertSame(404, $client->getResponse()->getStatusCode());
80+
81+
// format === any on the first id (attribute), canonical on the second one (default from config)
82+
// Uuid v6 canonical + uuid v6 canonical = ok
83+
$client->request('GET', '/attribute/uuid-v6/'.$uuidV6.'/no-attribute/uuid-v6/'.$uuidV6);
84+
$this->assertSame($uuidV6."\n".$uuidV6, $client->getResponse()->getContent());
85+
// Uuid v6 base 58 + uuid v6 canonical = ok
86+
$client->request('GET', '/attribute/uuid-v6/'.$uuidV6->toBase58().'/no-attribute/uuid-v6/'.$uuidV6);
87+
$this->assertSame($uuidV6."\n".$uuidV6, $client->getResponse()->getContent());
88+
// First id: uuid v1 !== uuid v6
89+
$client->request('GET', '/attribute/uuid-v6/'.$uuidV1.'/no-attribute/uuid-v6/'.$uuidV6);
90+
$this->assertSame(404, $client->getResponse()->getStatusCode());
91+
// Second id: base32 !== uuid v6 canonical
92+
$client->request('GET', '/attribute/uuid-v6/'.$uuidV6.'/no-attribute/uuid-v6/'.$uuidV6->toBase32());
93+
$this->assertSame(404, $client->getResponse()->getStatusCode());
94+
}
95+
96+
/**
97+
* @see UidController
98+
*/
99+
public function testArgumentValueResolverConfigCustom()
100+
{
101+
self::deleteTmpDir();
102+
$client = $this->createClient(['test_case' => 'Uid', 'root_config' => 'config_custom.yml']);
103+
104+
// format = rfc4122 (config)
105+
// Ulid rfc4122 = ok
106+
$client->request('GET', '/no-attribute/ulid/'.($ulid = new Ulid())->toRfc4122());
107+
$this->assertSame((string) $ulid, $client->getResponse()->getContent());
108+
// Ulid canonical !== rfc4122
109+
$client->request('GET', '/no-attribute/ulid/'.$ulid);
110+
$this->assertSame(404, $client->getResponse()->getStatusCode());
111+
// base32 !== rfc4122
112+
$client->request('GET', '/no-attribute/ulid/'.$ulid->toBase32());
113+
$this->assertSame(404, $client->getResponse()->getStatusCode());
114+
115+
// format === base58 (attribute)
116+
// Uuid v4 base58 = ok
117+
$client->request('GET', '/attribute/with-format/uuid-v4/'.($uuidV4 = new UuidV4())->toBase58());
118+
$this->assertSame((string) $uuidV4, $client->getResponse()->getContent());
119+
// rfc4122 !== base58
120+
$client->request('GET', '/attribute/with-format/uuid-v4/'.$uuidV4->toRfc4122());
121+
$this->assertSame(404, $client->getResponse()->getStatusCode());
122+
}
123+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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+
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
13+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
14+
15+
return [
16+
new FrameworkBundle(),
17+
new TestBundle(),
18+
];
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
imports:
2+
- { resource: "../config/default.yml" }
3+
4+
framework:
5+
uid:
6+
argument_value_resolver: ~
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
imports:
2+
- { resource: "../config/default.yml" }
3+
4+
framework:
5+
uid:
6+
argument_value_resolver:
7+
default_format: "rfc4122"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
uid:
2+
resource: "@TestBundle/Resources/config/routing.yml"

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
"symfony/translation": "<5.4",
9494
"symfony/twig-bridge": "<5.4",
9595
"symfony/twig-bundle": "<5.4",
96+
"symfony/uid": "<6.1",
9697
"symfony/validator": "<5.4",
9798
"symfony/web-profiler-bundle": "<5.4",
9899
"symfony/workflow": "<5.4"

0 commit comments

Comments
 (0)