Last active
September 17, 2019 06:51
-
-
Save romaricdrigon/4a7c9d5af79f6cee4ac15566505c36c2 to your computer and use it in GitHub Desktop.
FileTransport to store sent emails on disk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Email; | |
use Symfony\Bridge\Twig\Mime\TemplatedEmail; | |
use Symfony\Component\Finder\Finder; | |
use Symfony\Component\Mime\Email; | |
/** | |
* Helper to deal with messages as dumped by FileTransport. | |
* Everything is public and static, as it will be used in unit/functional tests. | |
*/ | |
class EmailFileHelper | |
{ | |
public static $path = __DIR__.'/../../../'.FileTransport::FOLDER; | |
private static $finder; // Singleton to save a little bit of memory | |
public static function countMessages() | |
{ | |
return self::getFinder()->count(); | |
} | |
public static function has(int $emailIndex): bool | |
{ | |
$files = iterator_to_array(self::getFinder()->getIterator(), false); | |
return isset($files[$emailIndex]); | |
} | |
public static function read(int $emailIndex): Email | |
{ | |
$files = iterator_to_array(self::getFinder()->getIterator(), false); | |
if (!isset($files[$emailIndex])) { | |
throw new \Exception('No emails available for index '.$emailIndex); | |
} | |
$file = $files[$emailIndex]; | |
$data = $file->getContents(); | |
$unserialized = unserialize($data); | |
if (TemplatedEmail::class === $unserialized['class']) { | |
// TemplatedEmail serialization format is incompatible | |
$email = new TemplatedEmail(); | |
$email->unserialize($unserialized['data']); | |
} else { | |
// We consider it is a normal Email | |
$email = new Email(); | |
$email->unserialize($unserialized['data']); | |
} | |
return $email; | |
} | |
public function getFilename(int $emailIndex): string | |
{ | |
$files = iterator_to_array(self::getFinder()->getIterator(), false); | |
if (!isset($files[$emailIndex])) { | |
throw new \Exception('No emails available for index '.$emailIndex); | |
} | |
return $files[$emailIndex]->getPathname(); | |
} | |
private static function getFinder(): Finder | |
{ | |
if (!self::$finder) { | |
self::$finder = (new Finder()) | |
->in(self::$path) | |
->name('*.ser') | |
->files() | |
; | |
} | |
return self::$finder; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Email; | |
use Symfony\Component\Filesystem\Filesystem; | |
use Symfony\Component\Mailer\SentMessage; | |
use Symfony\Component\Mailer\Transport\AbstractTransport; | |
use Symfony\Component\Mime\Email; | |
/** | |
* File transport used in tests, we store messages on disk. | |
*/ | |
class FileTransport extends AbstractTransport | |
{ | |
const FOLDER = 'var/emails'; | |
const FILE_EXTENSION = 'ser'; | |
private $path; | |
public function setProjectDir(string $path): void | |
{ | |
$this->path = sprintf('%s/%s', $path, self::FOLDER); | |
} | |
protected function doSend(SentMessage $message): void | |
{ | |
$filesystem = new Filesystem(); | |
if (!$filesystem->exists($this->path)) { | |
$filesystem->mkdir($this->path); | |
} | |
$filename = uniqid('message_'); | |
// We should get rendered Message - called "original", the other "RawMessage" is a Generator to generate body chunk-by-chunk. | |
$email = $message->getOriginalMessage(); | |
// We can serialize only Emails | |
if (!$email instanceof Email) { | |
return; | |
} | |
// We keep classname around, as TemplatedEmail and Email serialization are incompatible | |
$serialized = [ | |
'class' => get_class($email), | |
'data' => $email->serialize(), | |
]; | |
$filesystem->dumpFile( | |
sprintf('%s/%s.%s', $this->path, $filename, self::FILE_EXTENSION), | |
serialize($serialized) | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment