8000 Merge branch '6.4' into 7.0 · symfony/symfony@4a9d377 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

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 4a9d377

Browse files
committed
Merge branch '6.4' into 7.0
* 6.4: [Messenger] Don't drop stamps when message validation fails [WebProfilerBundle] Fix assignment to constant variable [Mailer] [Sendgrid] Use DataPart::getContentId() when DataPart::setContentId() is used.
2 parents a5e2616 + 3de527c commit 4a9d377

File tree

11 files changed

+190
-16
lines changed

11 files changed

+190
-16
lines changed

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
}
7676
7777
tab.addEventListener('click', function(e) {
78-
const activeTab = e.target || e.srcElement;
78+
let activeTab = e.target || e.srcElement;
7979
8080
/* needed because when the tab contains HTML contents, user can click */
8181
/* on any of those elements instead of their parent '<button>' element */

src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridApiTransportTest.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,45 @@ public function testTagAndMetadataHeaders()
245245
$this->assertSame('blue', $payload['personalizations'][0]['custom_args']['Color']);
246246
$this->assertSame('12345', $payload['personalizations'][0]['custom_args']['Client-ID']);
247247
}
248+
249+
public function testInlineWithCustomContentId()
250+
{
251+
$imagePart = (new DataPart('text-contents', 'text.txt'));
252+
$imagePart->asInline();
253+
$imagePart->setContentId('content-identifier@symfony');
254+
255+
$email = new Email();
256+
$email->addPart($imagePart);
257+
$envelope = new Envelope(new Address('alice@system.com'), [new Address('bob@system.com')]);
258+
259+
$transport = new SendgridApiTransport('ACCESS_KEY');
260+
$method = new \ReflectionMethod(SendgridApiTransport::class, 'getPayload');
261+
$payload = $method->invoke($transport, $email, $envelope);
262+
263+
$this->assertArrayHasKey('attachments', $payload);
264+
$this->assertCount(1, $payload['attachments']);
265+
$this->assertArrayHasKey('content_id', $payload['attachments'][0]);
266+
267+
$this->assertSame('content-identifier@symfony', $payload['attachments'][0]['content_id']);
268+
}
269+
270+
public function testInlineWithoutCustomContentId()
271+
{
272+
$imagePart = (new DataPart('text-contents', 'text.txt'));
273+
$imagePart->asInline();
274+
275+
$email = new Email();
276+
$email->addPart($imagePart);
277+
$envelope = new Envelope(new Address('alice@system.com'), [new Address('bob@system.com')]);
278+
279+
$transport = new SendgridApiTransport('ACCESS_KEY');
280+
$method = new \ReflectionMethod(SendgridApiTransport::class, 'getPayload');
281+
$payload = $method->invoke($transport, $email, $envelope);
282+
283+
$this->assertArrayHasKey('attachments', $payload);
284+
$this->assertCount(1, $payload['attachments']);
285+
$this->assertArrayHasKey('content_id', $payload['attachments'][0]);
286+
287+
$this->assertSame('text.txt', $payload['attachments'][0]['content_id']);
288+
}
248289
}

src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ private function getAttachments(Email $email): array
179179
];
180180

181181
if ('inline' === $disposition) {
182-
$att['content_id'] = $filename;
182+
$att['content_id'] = $attachment->hasContentId() ? $attachment->getContentId() : $filename;
183183
}
184184

185185
$attachments[] = $att;

src/Symfony/Component/Messenger/Exception/DelayedMessageHandlingException.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919
*
2020
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
2121
*/
22-
class DelayedMessageHandlingException extends RuntimeException implements WrappedExceptionsInterface
22+
class DelayedMessageHandlingException extends RuntimeException implements WrappedExceptionsInterface, EnvelopeAwareExceptionInterface
2323
{
24+
use EnvelopeAwareExceptionTrait;
2425
use WrappedExceptionsTrait;
2526

2627
private array $exceptions;
27-
private ?Envelope $envelope;
2828

2929
public function __construct(array $exceptions, ?Envelope $envelope = null)
3030
{
@@ -45,9 +45,4 @@ public function __construct(array $exceptions, ?Envelope $envelope = null)
4545

4646
parent::__construct($message, 0, $exceptions[array_key_first($exceptions)]);
4747
}
48-
49-
public function getEnvelope(): ?Envelope
50-
{
51-
return $this->envelope;
52-
}
5348
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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\Component\Messenger\Exception;
13+
14+
use Symfony\Component\Messenger\Envelope;
15+
16+
/**
17+
* @internal
18+
*/
19+
interface EnvelopeAwareExceptionInterface
20+
{
21+
public function getEnvelope(): ?Envelope;
22+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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\Component\Messenger\Exception;
13+
14+
use Symfony\Component\Messenger\Envelope;
15+
16+
/**
17+
* @internal
18+
*/
19+
trait EnvelopeAwareExceptionTrait
20+
{
21+
private ?Envelope $envelope = null;
22+
23+
public function getEnvelope(): ?Envelope
24+
{
25+
return $this->envelope;
26+
}
27+
}

src/Symfony/Component/Messenger/Exception/HandlerFailedException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
use Symfony\Component\Messenger\Envelope;
1515

16-
class HandlerFailedException extends RuntimeException implements WrappedExceptionsInterface
16+
class HandlerFailedException extends RuntimeException implements WrappedExceptionsInterface, EnvelopeAwareExceptionInterface
1717
{
1818
use WrappedExceptionsTrait;
1919

src/Symfony/Component/Messenger/Exception/ValidationFailedException.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,24 @@
1111

1212
namespace Symfony\Component\Messenger\Exception;
1313

14+
use Symfony\Component\Messenger\Envelope;
1415
use Symfony\Component\Validator\ConstraintViolationListInterface;
1516

1617
/**
1718
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
1819
*/
19-
class ValidationFailedException extends RuntimeException
20+
class ValidationFailedException extends RuntimeException implements EnvelopeAwareExceptionInterface
2021
{
22+
use EnvelopeAwareExceptionTrait;
23+
2124
private ConstraintViolationListInterface $violations;
2225
private object $violatingMessage;
2326

24-
public function __construct(object $violatingMessage, ConstraintViolationListInterface $violations)
27+
public function __construct(object $violatingMessage, ConstraintViolationListInterface $violations, ?Envelope $envelope = null)
2528
{
2629
$this->violatingMessage = $violatingMessage;
2730
$this->violations = $violations;
31+
$this->envelope = $envelope;
2832

2933
parent::__construct(sprintf('Message of type "%s" failed validation.', $this->violatingMessage::class));
3034
}

src/Symfony/Component/Messenger/Middleware/ValidationMiddleware.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope
3939

4040
$violations = $this->validator->validate($message, null, $groups);
4141
if (\count($violations)) {
42-
throw new ValidationFailedException($message, $violations);
42+
throw new ValidationFailedException($message, $violations, $envelope);
4343
}
4444

4545
return $stack->next()->handle($envelope, $stack);

src/Symfony/Component/Messenger/Tests/FailureIntegrationTest.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Symfony\Component\Messenger\EventListener\StopWorkerOnMessageLimitListener;
2525
use Symfony\Component\Messenger\Exception\DelayedMessageHandlingException;
2626
use Symfony\Component\Messenger\Exception\HandlerFailedException;
27+
use Symfony\Component\Messenger\Exception\ValidationFailedException;
2728
use Symfony\Component\Messenger\Handler\HandlerDescriptor;
2829
use Symfony\Component\Messenger\Handler\HandlersLocator;
2930
use Symfony\Component\Messenger\MessageBus;
@@ -32,6 +33,7 @@
3233
use Symfony\Component\Messenger\Middleware\FailedMessageProcessingMiddleware;
3334
use Symfony\Component\Messenger\Middleware\HandleMessageMiddleware;
3435
use Symfony\Component\Messenger\Middleware\SendMessageMiddleware;
36+
use Symfony\Component\Messenger\Middleware\ValidationMiddleware;
3537
use Symfony\Component\Messenger\Retry\MultiplierRetryStrategy;
3638
use Symfony\Component\Messenger\Stamp\BusNameStamp;
3739
use Symfony\Component\Messenger\Stamp\DispatchAfterCurrentBusStamp;
@@ -42,6 +44,9 @@
4244
use Symfony\Component\Messenger\Transport\Sender\SenderInterface;
4345
use Symfony\Component\Messenger\Transport\Sender\SendersLocator;
4446
use Symfony\Component\Messenger\Worker;
47+
use Symfony\Component\Validator\ConstraintViolation;
48+
use Symfony\Component\Validator\ConstraintViolationList;
49+
use Symfony\Component\Validator\Validator\ValidatorInterface;
4550

4651
class FailureIntegrationTest extends TestCase
4752
{
@@ -440,6 +445,87 @@ public function testStampsAddedByMiddlewaresDontDisappearWhenDelayedMessageFails
440445
$this->assertCount(1, $messagesWaiting);
441446
$this->assertSame('some.bus', $messagesWaiting[0]->last(BusNameStamp::class)?->getBusName());
442447
}
448+
449+
public function testStampsAddedByMiddlewaresDontDisappearWhenValidationFails()
450+
{
451+
$transport1 = new DummyFailureTestSenderAndReceiver();
452+
453+
$transports = [
454+
'transport1' => $transport1,
455+
];
456+
457+
$locator = $this->createMock(ContainerInterface::class);
458+
$locator->expects($this->any())
459+
->method('has')
460+
->willReturn(true);
461+
$locator->expects($this->any())
462+
->method('get')
463+
->willReturnCallback(fn ($transportName) => $transports[$transportName]);
464+
$senderLocator = new SendersLocator([], $locator);
465+
466+
$retryStrategyLocator = $this->createMock(ContainerInterface::class);
467+
$retryStrategyLocator->expects($this->any())
468+
->method('has')
469+
->willReturn(true);
470+
$retryStrategyLocator->expects($this->any())
471+
->method('get')
472+
->willReturn(new MultiplierRetryStrategy(1));
473+
474+
$violationList = new ConstraintViolationList([new ConstraintViolation('validation failed', null, [], null, null, null)]);
475+
$validator = $this->createMock(ValidatorInterface::class);
476+
$validator->expects($this->once())->method('validate')->willReturn($violationList);
477+
478+
$middlewareStack = new \ArrayIterator([
479+
new AddBusNameStampMiddleware('some.bus'),
480+
new ValidationMiddleware($validator),
481+
new SendMessageMiddleware($senderLocator),
482+
]);
483+
484+
$bus = new MessageBus($middlewareStack);
485+
486+
$transport1Handler = fn () => $bus->dispatch(new \stdClass(), [new DispatchAfterCurrentBusStamp()]);
487+
488+
$handlerLocator = new HandlersLocator([
489+
DummyMessage::class => [new HandlerDescriptor($transport1Handler)],
490+
]);
491+
492+
$middlewareStack->append(new HandleMessageMiddleware($handlerLocator));
493+
494+
$dispatcher = new EventDispatcher();
495+
496+
$dispatcher->addSubscriber(new SendFailedMessageForRetryListener($locator, $retryStrategyLocator));
497+
$dispatcher->addSubscriber(new StopWorkerOnMessageLimitListener(1));
498+
499+
$runWorker = function (string $transportName) use ($transports, $bus, $dispatcher): ?\Throwable {
500+
$throwable = null;
501+
$failedListener = function (WorkerMessageFailedEvent $event) use (&$throwable) {
502+
$throwable = $event->getThrowable();
503+
};
504+
$dispatcher->addListener(WorkerMessageFailedEvent::class, $failedListener);
505+
506+
$worker = new Worker([$transportName => $transports[$transportName]], $bus, $dispatcher);
507+
508+
$worker->run();
509+
510+
$dispatcher->removeListener(WorkerMessageFailedEvent::class, $failedListener);
511+
512+
return $throwable;
513+
};
514+
515+
// Simulate receive from external source
516+
$transport1->send(new Envelope(new DummyMessage('API')));
517+
518+
// Receive the message from "transport1"
519+
$throwable = $runWorker('transport1');
520+
521+
$this->assertInstanceOf(ValidationFailedException::class, $throwable, $throwable->getMessage());
522+
523+
$messagesWaiting = $transport1->getMessagesWaitingToBeReceived();
524+
525+
// Stamps should not be dropped on message that's queued for retry
526+
$this->assertCount(1, $messagesWaiting);
527+
$this->assertSame('some.bus', $messagesWaiting[0]->last(BusNameStamp::class)?->getBusName());
528+
}
443529
}
444530

445531
class DummyFailureTestSenderAndReceiver implements ReceiverInterface, SenderInterface

src/Symfony/Component/Messenger/Worker.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@
2222
use Symfony\Component\Messenger\Event\WorkerRunningEvent;
2323
use Symfony\Component\Messenger\Event\WorkerStartedEvent;
2424
use Symfony\Component\Messenger\Event\WorkerStoppedEvent;
25-
use Symfony\Component\Messenger\Exception\DelayedMessageHandlingException;
26-
use Symfony\Component\Messenger\Exception\HandlerFailedException;
25+
use Symfony\Component\Messenger\Exception\EnvelopeAwareExceptionInterface;
2726
use Symfony\Component\Messenger\Exception\RejectRedeliveredMessageException;
2827
use Symfony\Component\Messenger\Exception\RuntimeException;
2928
use Symfony\Component\Messenger\Stamp\AckStamp;
@@ -189,7 +188,7 @@ private function ack(): bool
189188
$receiver->reject($envelope);
190189
}
191190

192-
if ($e instanceof HandlerFailedException || ($e instanceof DelayedMessageHandlingException && null !== $e->getEnvelope())) {
191+
if ($e instanceof EnvelopeAwareExceptionInterface && null !== $e->getEnvelope()) {
193192
$envelope = $e->getEnvelope();
194193
}
195194

0 commit comments

Comments
 (0)
0