Я хотел бы обсудить ошибку, связанную с вложениями электронной почты в Symfony, и предложить возможное исправление.
Мне очень нужна эта ошибка исправлено быстро.
Справочная информация
Я использовал почтовую программу Laravel 10 вместе с Symfony Mailer и обнаружил ошибку, связанную с функцией аварийного переключения, когда первая почтовая программа вышла из строя. для отправки электронного письма.
Конфигурация аварийного переключения
Моя настройка аварийного переключения следующая:
Основной драйвер почтовой программы : Mailgun
Вторичный драйвер почтовой программы: Amazon SES
Описание проблемы
Когда не удается отправить электронное письмо с помощью Mailgun, система пытается отправить электронное письмо через Amazon SES. Однако я обнаружил, что электронные письма, отправленные через Amazon SES, содержат неработающие источники изображений (src), из-за чего изображения в электронных письмах отображаются некорректно.
Версия пакета
symfony/mailer 6.4.8
symfony/mailgun-mailer 7.1.1
Мой локальный тест отладки
Когда я меняю первый драйвер на SMTP, он работает хорошо.
Я делаю это перед классом FailoverTransport, перед первой отправкой.
$s = new Symfony\Component\Mailer\SentMessage($message,$envelope);
$s->toString();
Вложение будет иметь неправильный путь к источнику.
Когда я глубоко скопировал сообщение, все работало хорошо !!!
$current = deep_copy($message)
$s = new Symfony\Component\Mailer\SentMessage($current,$envelope);
$s->toString();
Следующая информация для справки
Вот первый источник электронной почты.
Это нормально и работает хорошо .
Это будет использоваться для сравнения со вторым источником электронной почты.
Источником изображения является cid:V9J4rKBvmB, и он будет заменен на cid: d3a788f4cbf3a6aab32dcacde69a2e34@symfony, что приводит к следующему выводу:
Content-Type: multipart/related;
...
\
....
\--KGCwwzRU
Content-ID: d3a788f4cbf3a6aab32dcacde69a2e34@symfony
Content-Type: image/png; name="d3a788f4cbf3a6aab32dcacde69a2e34@symfony"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
name="d3a788f4cbf3a6aab32dcacde69a2e34@symfony"; filename=V9J4rKBvmB
Вот второе изображение. Источник неверен, поэтому его невозможно отобразить.
Источник проблемного изображения по электронной почте находится здесь:
Источник изображения: cid:L7HALxfBwi .
Он должен быть обновлен до Content-ID cid:2eabc9240b3557c72ad65e92a60f7f57@symfony, но результат по-прежнему будет cid:L7HALxfBwi.
Content-Type: multipart/mixed;
\
...
\--TG5g10Dt
Content-ID: 2eabc9240b3557c72ad65e92a60f7f57@symfony
Content-Type: image/png; name="2eabc9240b3557c72ad65e92a60f7f57@symfony"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
name="2eabc9240b3557c72ad65e92a60f7f57@symfony"; filename=L7HALxfBwi
Я обнаружил, что эта проблема может быть связана с классом Symfony\Component\Mailer\Transport\AbstractTransport, в частности с функцией отправки.
$message = clone $message; // this clone haven't clone the inner object var
поддельный код для моего теста
Я использую Symfony Mailer в Laravel 10. Вот пример кода (извините для демонстрационного кода):
// Set the mailgun always fail
config()->set('services.mailgun.endpoint', '127.0.0.1');
// Set the mail mailers configuration for failover
config()->set('mail.mailers.failover.mailers', ['mailgun', 'ses']);
// Get the mail manager instance and set the Symfony transporter
$mail_manager = app()->get('mail.manager');
$mail_manager->setSymfonyTransport($mail_manager->createSymfonyTransport(config('mail.mailers.failover')));
// Send the email using the specified driver
Mail::mailer($driver)->send(new MailableView(1, "The $driver mailable view test email"));
// Use Illuminate\Mail\Mailable to define your Mailable class
use Illuminate\Mail\Mailable;
class Mailable extends IlluminateMailable
{
public function build()
{
// Compose the email view
return $this->view('emails.mailable_view_test.email_view')
->text('emails.mailable_view_test.email_view_text')
->sender('xxx', $name)
->from('xxx', $name)
->replyTo('xxx', $name)
->to('xxx', 'xxx')
->with([
'name' => 'xxx',
'url' => 'xxx',
])
->subject($this->title);
}
}
в шаблоне лезвия
{{ $subject }}
Hello, {{ $name }}
Welcome to our service. Please visit this link for more information.
embedData($logo, 'logo.png', 'image/png') }}" alt="Logo">
Попробуйте исправить
Я пытался исправить проблему в файле, расположенном по адресуvendor/symfony/mailer/ Transport/RoundRobinTransport.php.
Это сработало, когда я внес следующие изменения:
Похоже, что вложения $message являются ссылкой. Операция клонирования не может правильно клонировать объекты вложений. Поэтому я изменил его, чтобы использовать deep_copy для выполнения глубокого клонирования для каждой операции отправки.
Я также обнаружил, что драйвер Mailgun меняет CID вложений.
Вот измененный раздел кода:
public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMessage
{
$exception = null;
while ($transport = $this->getNextTransport()) {
try {
$currentMessage = deep_copy($message); //here i change
return $transport->send($currentMessage, Envelope::create($currentMessage)); //here i change
} catch (TransportExceptionInterface $e) {
$exception ??= new TransportException('All transports failed.');
$exception->appendDebug(sprintf("Transport \"%s\": %s\n", $transport, $e->getDebug()));
$this->deadTransports[$transport] = microtime(true);
}
}
throw $exception ?? new TransportException('No transports found.');
}
Дополнительный контекст
вот дамп $message с помощью функции laravel dd(), этот контент для показа клонирования не будет клонировать #1826 объект $message->вложения
первое письмо var $message дамп, это нормально для сравнения второго неправильного
-attachments: array:1 [
0 => Symfony\Component\Mime\Part\DataPart^ {#1826
-headers: Symfony\Component\Mime\Header\Headers^ {#1829
-headers: []
-lineLength: 76
}
#_headers: ? Symfony\Component\Mime\Header\Headers
-body: Symfony\Component\Mime\Part\File^ {#1818
-path: "/User/rick/xxxx/img/logo-negative.png"
-filename: null
}
-charset: null
-subtype: "png"
-disposition: "inline"
-name: "4nF4PcToTi"
-encoding: "base64"
-seekable: null
#_parent: ? array
-filename: "4nF4PcToTi"
-mediaType: "image"
-cid: null
}
]
-cachedBody: null
с неработающим источником изображения из дампа $message второго электронного письма.
-attachments: array:1 [
0 => Symfony\Component\Mime\Part\DataPart^ {#1826 //object is same
-headers: Symfony\Component\Mime\Header\Headers^ {#1829 //object is same
-headers: array:1 [
"content-id" => array:1 [
0 => Symfony\Component\Mime\Header\IdentificationHeader^ {#1932
-name: "Content-ID"
-lineLength: 76
-lang: null
-charset: "utf-8"
-ids: array:1 [
0 => "9b83b7043798ef148b6b46ac184ca696@symfony"
]
-idsAsAddresses: array:1 [
0 => Symfony\Component\Mime\Address^ {#1933
-address: "9b83b7043798ef148b6b46ac184ca696@symfony"
-name: ""
}
]
}
]
]
-lineLength: 76
}
#_headers: ? Symfony\Component\Mime\Header\Headers
-body: Symfony\Component\Mime\Part\File^ {#1818
-path: "/User/rick/xxxx/img/logo-negative.png"
-filename: null
}
-charset: null
-subtype: "png"
-disposition: "inline"
-name: "7a7a484a463c3667a9e55d610c2f0641@symfony"
-encoding: "base64"
-seekable: null
#_parent: ? array
-filename: "4nF4PcToTi"
-mediaType: "image"
-cid: "7a7a484a463c3667a9e55d610c2f0641@symfony"
}
]
-cachedBody: null
Подробнее здесь: https://stackoverflow.com/questions/786 ... s-wrong-in