Skip to content

TemplatedEmail automatic cid #42731

Closed
Closed
@Varfendell

Description

@Varfendell

Description
As gmail is the most used for message, and it remove base64encoded image in mail, maybe we should automatically transform image from base64 to cid when they exist in html.
I came in mind with this because I made up a functionnality which allow user to customize email (using some WYSIWYG). When sending mail, images are not displayed in gmail. My solution was to work on the html using Crawler and replace all base64 image found with embed image.

The crawler part could be automatically done (using a bool attribute to activate it).

Example
This is what i have done, it will display image in gmail without attachment

<?php

namespace App\Service;

use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;

class MailerService
{
	/**
	 * @var MailerInterface
	 */
	private MailerInterface $mailer;

	/**
	 * UserManager constructor.
	 *
	 * @param MailerInterface $mailer
	 */
	public function __construct(MailerInterface $mailer)
	{
		$this->mailer = $mailer;
	}

	/**
	 * @throws TransportExceptionInterface
	 */
	public function sendEmail(): void
	{
		$html = '<html lang="fr">
				<body>
				<img src="data:image/png;base64,iVibUGHVYUTGVuiyboiu..." alt="test1">
				<img src="data:image/png;base64,RviuinUBUIHBUIBUuyio..." alt="test2">
				<img src="data:image/png;base64,InniNBuiOIunoiuipiop..." alt="test3">
				</body>
				</html>';


		$templatedEmail = (new TemplatedEmail())
			->to('some@email.fr')
			->subject('testing images');

		$crawler = new Crawler($html);
		$images = $crawler->filter('img');
		foreach ($images as $key => $image) {
			$src = $image->attributes->getNamedItem('src');
			if (strpos($src->nodeValue, 'data:image') === 0) {
				$base64EncodedImage = explode(',', $src->nodeValue)[1];
				$extension = explode('/', explode(';', $src->nodeValue)[0])[1];
				$templatedEmail->embed(base64_decode($base64EncodedImage), 'image' . $key . '.' . $extension);
				$src->nodeValue = 'cid:image' . $key . '.' . $extension;
			}

		}
		$templatedEmail->html($crawler->html());
		$this->mailer->send($templatedEmail);
	}
}

This is what i have done first and it didn't display image

<?php

namespace App\Service;

use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;

class MailerService
{
	/**
	 * @var MailerInterface
	 */
	private MailerInterface $mailer;

	/**
	 * UserManager constructor.
	 *
	 * @param MailerInterface $mailer
	 */
	public function __construct(MailerInterface $mailer)
	{
		$this->mailer = $mailer;
	}

	/**
	 * @throws TransportExceptionInterface
	 */
	public function sendEmail(): void
	{
		$html = '<html lang="fr">
				<body>
				<img src="data:image/png;base64,iVibUGHVYUTGVuiyboiu..." alt="test1">
				<img src="data:image/png;base64,RviuinUBUIHBUIBUuyio..." alt="test2">
				<img src="data:image/png;base64,InniNBuiOIunoiuipiop..." alt="test3">
				</body>
				</html>';

		$templatedEmail = (new TemplatedEmail())
			->to('some@email.fr')
			->subject('testing images')
			->html($html);
		$this->mailer->send($templatedEmail);
	}
}

Here is what i propose to add

<?php

namespace App\Service;

use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;

class MailerService
{
	/**
	 * @var MailerInterface
	 */
	private MailerInterface $mailer;

	/**
	 * UserManager constructor.
	 *
	 * @param MailerInterface $mailer
	 */
	public function __construct(MailerInterface $mailer)
	{
		$this->mailer = $mailer;
	}

	/**
	 * @throws TransportExceptionInterface
	 */
	public function sendEmail(): void
	{
		$html = '<html lang="fr">
				<body>
				<img src="data:image/png;base64,iVibUGHVYUTGVuiyboiu..." alt="test1">
				<img src="data:image/png;base64,RviuinUBUIHBUIBUuyio..." alt="test2">
				<img src="data:image/png;base64,InniNBuiOIunoiuipiop..." alt="test3">
				</body>
				</html>';

		$templatedEmail = (new TemplatedEmail())
			->to('some@email.fr')
			->subject('testing images')
			->html($html)
			/** This option could activate automatically the crawler */
			->automaticEmbedImage(true);
		$this->mailer->send($templatedEmail);
	}
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions