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 49e13b6

Browse filesBrowse files
Merge branch '8.0' into 8.1
* 8.0: [Validator] Fix Compound constraint with nested Composite and validation groups [Messenger][AmazonSqs] Do not override queue-level DelaySeconds when no DelayStamp is set
2 parents cd39bc5 + 28bae08 commit 49e13b6
Copy full SHA for 49e13b6

5 files changed

+110-6Lines changed: 110 additions & 6 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsSenderTest.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsSenderTest.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function testSendWithAmazonSqsFifoStamp()
4646

4747
$connection = $this->createMock(Connection::class);
4848
$connection->expects($this->once())->method('send')
49-
->with($encoded['body'], $encoded['headers'], 0, $stamp->getMessageGroupId(), $stamp->getMessageDeduplicationId());
49+
->with($encoded['body'], $encoded['headers'], null, $stamp->getMessageGroupId(), $stamp->getMessageDeduplicationId());
5050

5151
$serializer = $this->createMock(SerializerInterface::class);
5252
$serializer->expects($this->once())->method('encode')->with($envelope)->willReturn($encoded);
@@ -64,7 +64,7 @@ public function testSendWithAmazonSqsXrayTraceHeaderStamp()
6464

6565
$connection = $this->createMock(Connection::class);
6666
$connection->expects($this->once())->method('send')
67-
->with($encoded['body'], $encoded['headers'], 0, null, null, $stamp->getTraceId());
67+
->with($encoded['body'], $encoded['headers'], null, null, null, $stamp->getTraceId());
6868

6969
$serializer = $this->createMock(SerializerInterface::class);
7070
$serializer->expects($this->once())->method('encode')->with($envelope)->willReturn($encoded);
Collapse file

‎src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/AmazonSqsSender.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/AmazonSqsSender.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function send(Envelope $envelope): Envelope
3636

3737
/** @var DelayStamp|null $delayStamp */
3838
$delayStamp = $envelope->last(DelayStamp::class);
39-
$delay = null !== $delayStamp ? (int) ceil($delayStamp->getDelay() / 1000) : 0;
39+
$delay = null !== $delayStamp ? (int) ceil($delayStamp->getDelay() / 1000) : null;
4040

4141
$messageGroupId = null;
4242
$messageDeduplicationId = null;
Collapse file

‎src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/Connection.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/Connection.php
+6-3Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ public function getMessageCount(): int
357357
return (int) ($attributes[QueueAttributeName::APPROXIMATE_NUMBER_OF_MESSAGES] ?? 0);
358358
}
359359

360-
public function send(string $body, array $headers, int $delay = 0, ?string $messageGroupId = null, ?string $messageDeduplicationId = null, ?string $xrayTraceId = null): void
360+
public function send(string $body, array $headers, ?int $delay = null, ?string $messageGroupId = null, ?string $messageDeduplicationId = null, ?string $xrayTraceId = null): void
361361
{
362362
if ($this->configuration['auto_setup']) {
363363
$this->setup();
@@ -366,12 +366,15 @@ public function send(string $body, array $headers, int $delay = 0, ?string $mess
366366
$parameters = [
367367
'QueueUrl' => $this->getQueueUrl(),
368368
'MessageBody' => $body,
369-
// Maximum delay is 15 minutes. See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-timers.html.
370-
'DelaySeconds' => min(900, $delay),
371369
'MessageAttributes' => [],
372370
'MessageSystemAttributes' => [],
373371
];
374372

373+
if (null !== $delay) {
374+
// Maximum delay is 15 minutes. See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-timers.html.
375+
$parameters['DelaySeconds'] = min(900, $delay);
376+
}
377+
375378
$specialHeaders = [];
376379
foreach ($headers as $name => $value) {
377380
if ('.' === $name[0] || self::MESSAGE_ATTRIBUTE_NAME === $name || \strlen($name) > 256 || str_ends_with($name, '.') || str_starts_with($name, 'AWS.') || str_starts_with($name, 'Amazon.') || preg_match('/([^a-zA-Z0-9_\.-]+|\.\.)/', $name)) {
Collapse file

‎src/Symfony/Component/Validator/Constraints/Compound.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Constraints/Compound.php
+42Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,16 @@ public function __construct(mixed $options = null, ?array $groups = null, mixed
3232

3333
$this->constraints = $this->getConstraints([]);
3434

35+
if (null !== $groups) {
36+
// reset nested groups so that Composite::__construct() does not run its subset check
37+
self::resetNestedConstraintsGroups($this->constraints);
38+
}
39+
3540
parent::__construct($options, $groups, $payload);
41+
42+
if (null !== $groups) {
43+
self::propagateGroupsToNestedConstraints($this->constraints, $this->groups);
44+
}
3645
}
3746

3847
final protected function getCompositeOption(): string
@@ -51,4 +60,37 @@ final public function validatedBy(): string
5160
* @return Constraint[]
5261
*/
5362
abstract protected function getConstraints(array $options): array;
63+
64+
private static function resetNestedConstraintsGroups(array $constraints): void
65+
{
66+
foreach ($constraints as $constraint) {
67+
if (!$constraint instanceof Constraint) {
68+
continue;
69+
}
70+
if ($constraint instanceof Composite) {
71+
// skip Composites with explicit groups: their subset check is the user's contract
72+
if ([Constraint::DEFAULT_GROUP] !== $constraint->groups) {
73+
continue;
74+
}
75+
self::resetNestedConstraintsGroups($constraint->getNestedConstraints());
76+
}
77+
unset($constraint->groups);
78+
}
79+
}
80+
81+
private static function propagateGroupsToNestedConstraints(array $constraints, array $groups): void
82+
{
83+
foreach ($constraints as $constraint) {
84+
if (!$constraint instanceof Constraint) {
85+
continue;
86+
}
87+
if ($constraint instanceof Composite && $groups !== $constraint->groups) {
88+
continue;
89+
}
90+
$constraint->groups = $groups;
91+
if ($constraint instanceof Composite) {
92+
self::propagateGroupsToNestedConstraints($constraint->getNestedConstraints(), $groups);
93+
}
94+
}
95+
}
5496
}
Collapse file

‎src/Symfony/Component/Validator/Tests/Constraints/CompoundTest.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Tests/Constraints/CompoundTest.php
+59Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Validator\Constraints\Compound;
16+
use Symfony\Component\Validator\Constraints\Length;
17+
use Symfony\Component\Validator\Constraints\NotBlank;
18+
use Symfony\Component\Validator\Constraints\Sequentially;
1619

1720
class CompoundTest extends TestCase
1821
{
@@ -24,6 +27,36 @@ public function testGroupsAndPayload()
2427
$this->assertSame(['my-group', 'my-other-group'], $compound->groups);
2528
$this->assertSame($payload, $compound->payload);
2629
}
30+
31+
public function testGroupsArePropagatedToNestedCompositeConstraints()
32+
{
33+
$compound = new CompoundWithSequentially(groups: ['my-group']);
34+
35+
$this->assertSame(['my-group'], $compound->groups);
36+
37+
$sequentially = $compound->constraints[0];
38+
$this->assertInstanceOf(Sequentially::class, $sequentially);
39+
$this->assertSame(['my-group'], $sequentially->groups);
40+
41+
foreach ($sequentially->constraints as $nestedConstraint) {
42+
$this->assertSame(['my-group'], $nestedConstraint->groups);
43+
}
44+
}
45+
46+
public function testExplicitGroupsOnNestedCompositeArePreserved()
47+
{
48+
$compound = new CompoundWithExplicitlyGroupedSequentially(groups: ['outer', 'inner']);
49+
50+
$this->assertSame(['outer', 'inner'], $compound->groups);
51+
52+
$sequentially = $compound->constraints[0];
53+
$this->assertInstanceOf(Sequentially::class, $sequentially);
54+
$this->assertSame(['inner'], $sequentially->groups);
55+
56+
foreach ($sequentially->constraints as $nestedConstraint) {
57+
$this->assertSame(['inner'], $nestedConstraint->groups);
58+
}
59+
}
2760
}
2861

2962
class EmptyCompound extends Compound
@@ -33,3 +66,29 @@ protected function getConstraints(array $options): array
3366
return [];
3467
}
3568
}
69+
70+
class CompoundWithSequentially extends Compound
71+
{
72+
protected function getConstraints(array $options): array
73+
{
74+
return [
75+
new Sequentially([
76+
new NotBlank(),
77+
new Length(min: 3),
78+
]),
79+
];
80+
}
81+
}
82+
83+
class CompoundWithExplicitlyGroupedSequentially extends Compound
84+
{
85+
protected function getConstraints(array $options): array
86+
{
87+
return [
88+
new Sequentially(constraints: [
89+
new NotBlank(),
90+
new Length(min: 3),
91+
], groups: ['inner']),
92+
];
93+
}
94+
}

0 commit comments

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