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

Appearance settings

Commit b2c1b7f

Browse filesBrowse files
committed
[Uid] Add the UidValueResolver argument value resolver
1 parent b2e7fcd commit b2c1b7f
Copy full SHA for b2c1b7f

File tree

18 files changed

+544
-1
lines changed
Filter options

18 files changed

+544
-1
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+9Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+11Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
+18Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/uid.php
+4Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+4Lines 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
];
+67Lines 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 <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+
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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml
+4Lines 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"
+123Lines 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 <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+
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+
}
+18Lines 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 <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+
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+
];
+6Lines 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: ~
+7Lines 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"
+2Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/composer.json
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"symfony/string": "^5.4|^6.0",
5959
"symfony/translation": "^5.4|^6.0",
6060
"symfony/twig-bundle": "^5.4|^6.0",
61+
"symfony/uid": "^6.1",
6162
"symfony/validator": "^5.4|^6.0",
6263
"symfony/workflow": "^5.4|^6.0",
6364
"symfony/yaml": "^5.4|^6.0",
@@ -93,6 +94,7 @@
9394
"symfony/translation": "<5.4",
9495
"symfony/twig-bridge": "<5.4",
9596
"symfony/twig-bundle": "<5.4",
97+
"symfony/uid": "<6.1",
9698
"symfony/validator": "<5.4",
9799
"symfony/web-profiler-bundle": "<5.4",
98100
"symfony/workflow": "<5.4"

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.