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

[Mailer] Fix the possibility to set a From header from MessageListener #31774

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
[Mailer] fixed the possibility to set a From header from MessageListener
  • Loading branch information
fabpot committed Jun 1, 2019
commit f4254e6f5e74406ca7cbcd1606d0dd3c2032d0c7
105 changes: 105 additions & 0 deletions 105 src/Symfony/Component/Mailer/DelayedSmtpEnvelope.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Mailer;

use Symfony\Component\Mailer\Exception\InvalidArgumentException;
use Symfony\Component\Mailer\Exception\LogicException;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Header\Headers;
use Symfony\Component\Mime\Message;
use Symfony\Component\Mime\RawMessage;

/**
* @author Fabien Potencier <fabien@symfony.com>
*
* @experimental in 4.3
*
* @internal
*/
final class DelayedSmtpEnvelope extends SmtpEnvelope
{
private $senderSet = false;
private $recipientsSet = false;
private $message;

public function __construct(RawMessage $message)
{
if (!$message instanceof Message) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to change the type-hint instead? If we want to support any other message in the future we can still change the type then.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. I've done it that way to get a "better" error message.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it means that the user will only get an error at runtime if they didn't discover before that Message instances are required here. With a proper type hint they can be warned before.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would they be warned before? I suppose you're thinking about static analysis. Not sure what to do.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case, that's independent from this PR as I'm doing the same at several other places (and this code is copy/pasted from SmtpEnvelope).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// FIXME: parse the raw message to create the envelope?
throw new InvalidArgumentException(sprintf('Unable to create an SmtpEnvelope from a "%s" message.', RawMessage::class));
}

$this->message = $message;
}

public function setSender(Address $sender): void
{
parent::setSender($sender);

$this->senderSet = true;
}

public function getSender(): Address
{
if ($this->senderSet) {
return parent::getSender();
}

return self::getSenderFromHeaders($this->message->getHeaders());
}

public function setRecipients(array $recipients): void
{
parent::setRecipients($recipients);

$this->recipientsSet = parent::getRecipients();
}

/**
* @return Address[]
*/
public function getRecipients(): array
{
if ($this->recipientsSet) {
return parent::getRecipients();
}

return self::getRecipientsFromHeaders($this->message->getHeaders());
}

private static function getRecipientsFromHeaders(Headers $headers): array
{
$recipients = [];
foreach (['to', 'cc', 'bcc'] as $name) {
foreach ($headers->getAll($name) as $header) {
$recipients = array_merge($recipients, $header->getAddresses());
}
}

return $recipients;
}

private static function getSenderFromHeaders(Headers $headers): Address
{
if ($return = $headers->get('Return-Path')) {
return $return->getAddress();
}
if ($sender = $headers->get('Sender')) {
return $sender->getAddress();
}
if ($from = $headers->get('From')) {
return $from->getAddresses()[0];
}

throw new LogicException('Unable to determine the sender of the message.');
}
}
39 changes: 1 addition & 38 deletions 39 src/Symfony/Component/Mailer/SmtpEnvelope.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
namespace Symfony\Component\Mailer;

use Symfony\Component\Mailer\Exception\InvalidArgumentException;
use Symfony\Component\Mailer\Exception\LogicException;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Header\Headers;
use Symfony\Component\Mime\Message;
use Symfony\Component\Mime\NamedAddress;
use Symfony\Component\Mime\RawMessage;

Expand All @@ -40,14 +37,7 @@ public function __construct(Address $sender, array $recipients)

public static function create(RawMessage $message): self
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we should keep this method.

{
if ($message instanceof Message) {
$headers = $message->getHeaders();

return new self(self::getSenderFromHeaders($headers), self::getRecipientsFromHeaders($headers));
}

// FIXME: parse the raw message to create the envelope?
throw new InvalidArgumentException(sprintf('Unable to create an SmtpEnvelope from a "%s" message.', RawMessage::class));
return new DelayedSmtpEnvelope($message);
}

public function setSender(Address $sender): void
Expand Down Expand Up @@ -84,31 +74,4 @@ public function getRecipients(): array
{
return $this->recipients;
}

private static function getRecipientsFromHeaders(Headers $headers): array
{
$recipients = [];
foreach (['to', 'cc', 'bcc'] as $name) {
foreach ($headers->getAll($name) as $header) {
$recipients = array_merge($recipients, $header->getAddresses());
}
}

return $recipients;
}

private static function getSenderFromHeaders(Headers $headers): Address
{
if ($return = $headers->get('Return-Path')) {
return $return->getAddress();
}
if ($sender = $headers->get('Sender')) {
return $sender->getAddress();
}
if ($from = $headers->get('From')) {
return $from->getAddresses()[0];
}

throw new LogicException('Unable to determine the sender of the message.');
}
}
7 changes: 4 additions & 3 deletions 7 src/Symfony/Component/Mailer/Tests/SmtpEnvelopeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,13 @@ public function testSenderFromHeaders()
$this->assertEquals('from@symfony.com', $e->getSender()->getAddress());
}

public function testSenderFromHeadersWithoutData()
public function testSenderFromHeadersWithoutFrom()
{
$this->expectException(\LogicException::class);
$headers = new Headers();
$headers->addMailboxListHeader('To', ['from@symfony.com']);
SmtpEnvelope::create(new Message($headers));
$e = SmtpEnvelope::create($message = new Message($headers));
$message->getHeaders()->addMailboxListHeader('From', ['from@symfony.com']);
$this->assertEquals('from@symfony.com', $e->getSender()->getAddress());
}

public function testRecipientsFromHeaders()
Expand Down
3 changes: 2 additions & 1 deletion 3 src/Symfony/Component/Mailer/Transport/AbstractTransport.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Psr\Log\NullLogger;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Mailer\DelayedSmtpEnvelope;
use Symfony\Component\Mailer\Event\MessageEvent;
use Symfony\Component\Mailer\Exception\TransportException;
use Symfony\Component\Mailer\SentMessage;
Expand Down Expand Up @@ -62,7 +63,7 @@ public function send(RawMessage $message, SmtpEnvelope $envelope = null): ?SentM
$envelope = clone $envelope;
} else {
try {
$envelope = SmtpEnvelope::create($message);
$envelope = new DelayedSmtpEnvelope($message);
} catch (\Exception $e) {
throw new TransportException('Cannot send message without a valid envelope.', 0, $e);
}
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.