A robust PHP library that provides bidirectional conversion between Nette Mail messages and Doctrine entities. This package allows you to persist email messages in a database, enabling email queuing, logging, retry mechanisms, and comprehensive email history tracking.
- Bidirectional Conversion - Seamlessly convert
Nette\Mail\Messageto Doctrine entity and back - Full Email Support - Handles all standard email fields: From, To, CC, BCC, Reply-To, Return-Path, Priority
- Attachment Management - Automatic serialization and storage of file attachments with content-hash based deduplication
- Tracking Support - Automatic injection of pair tokens for email tracking and pairing
- Nette Integration - First-class support for Nette Framework via DI extension
- Type Safety - Full PHP 8.0+ type declarations with PHPStan level 9 verification
The library follows a clean, service-oriented architecture with clear separation of concerns:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your Application โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MessageEntity โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ toEntity() โโโโโโโโโโโโโโโถโ DoctrineMessage โ โ
โ โ toMessage() โโโโโโโโโโโโโโโโ (Doctrine Entity) โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ
โ โผ โผ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Helpers โ โ Attachment Storage โ โ
โ โ (Header Format) โ โ (File System) โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Nette\Mail\Message โ
โ (Standard Mail Object) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The core Doctrine entity (DoctrineMessage) maps to the core__email_message database table and stores:
| Field | Type | Description |
|---|---|---|
id |
integer | Auto-generated primary key |
from |
string | Sender email address |
to |
string | Primary recipient |
subject |
string | Email subject line |
htmlBody |
text (nullable) | HTML content of the email |
textBody |
text (nullable) | Plain text content |
cc |
json | Array of CC recipients |
bcc |
json | Array of BCC recipients |
replyTo |
json | Array of Reply-To addresses |
returnPath |
string (nullable) | Return path for bounces |
priority |
smallint | Email priority (default: normal) |
attachments |
json | Attachment metadata array |
The main service class responsible for:
- Converting
Nette\Mail\Messageobjects toDoctrineMessageentities viatoEntity() - Converting
DoctrineMessageentities back toNette\Mail\MessageviatoMessage() - Managing attachment serialization/deserialization
- Automatic entity persistence during conversion
A static utility class providing:
formatHeader()- Formats email headers from various array formats to string representationgetFileNameByContentDisposition()- Extracts filename from Content-Disposition headerprocessHtmlMail()- Injects tracking pair tokens into HTML email body
The DoctrineMailMessageExtension provides automatic integration with Nette Framework:
- Registers entity paths for Doctrine ORM annotation discovery
- Creates attachment storage directory in temp path
- Registers
MessageEntityas a service
It's best to use Composer for installation, and you can also find the package on Packagist and GitHub.
To install, simply use the command:
$ composer require baraja-core/doctrine-mail-messageYou can use the package manually by creating an instance of the internal classes, or register a DIC extension to link the services directly to the Nette Framework.
- PHP 8.0 or higher
- Doctrine ORM 2.7+
- Doctrine DBAL 3.2+
- Nette Framework 3.0+ (for DI integration)
Register the extension in your NEON configuration file:
extensions:
doctrineMailMessage: Baraja\DoctrineMailMessage\DoctrineMailMessageExtensionThe extension will automatically:
- Register the entity path for Doctrine annotations
- Create the
emailer-attachmentsdirectory in your temp folder - Register the
MessageEntityservice in the DI container
If not using Nette Framework, create the service manually:
use Baraja\DoctrineMailMessage\MessageEntity;
use Doctrine\ORM\EntityManagerInterface;
$messageEntity = new MessageEntity(
attachmentBasePath: '/path/to/temp/emailer-attachments',
entityManager: $entityManager, // Your EntityManagerInterface instance
logger: $logger, // Optional PSR-3 LoggerInterface
);use Nette\Mail\Message;
use Baraja\DoctrineMailMessage\MessageEntity;
// Create a standard Nette Mail message
$message = new Message;
$message->setFrom('[email protected]', 'Sender Name')
->addTo('[email protected]', 'Recipient Name')
->setSubject('Hello World')
->setHtmlBody('<p>This is an <b>HTML</b> email.</p>')
->setBody('This is a plain text email.');
// Convert to Doctrine entity (automatically persisted)
/** @var MessageEntity $messageEntity */
$doctrineMessage = $messageEntity->toEntity($message);
// Entity is now persisted and has an ID
echo $doctrineMessage->getId(); // e.g., 42use Baraja\DoctrineMailMessage\DoctrineMessage;
// Load entity from database
$doctrineMessage = $entityManager->find(DoctrineMessage::class, 42);
// Convert back to Nette Mail Message
$message = $messageEntity->toMessage($doctrineMessage);
// Now you can send it via any Nette mailer
$mailer->send($message);Attachments are automatically handled during conversion:
$message = new Message;
$message->setFrom('[email protected]')
->addTo('[email protected]')
->setSubject('Document Attached')
->setHtmlBody('<p>Please find the document attached.</p>')
->addAttachment('document.pdf', $pdfContent, 'application/pdf');
// Attachments are serialized to filesystem
$doctrineMessage = $messageEntity->toEntity($message);
// When converting back, attachments are restored
$restoredMessage = $messageEntity->toMessage($doctrineMessage);Attachment files are stored in the configured temp directory with content-hash based naming for deduplication.
$message = new Message;
$message->setFrom('[email protected]')
->addTo('[email protected]')
->addCc('[email protected]')
->addCc('[email protected]')
->addBcc('[email protected]')
->addReplyTo('[email protected]')
->setSubject('Multi-recipient Email');
$doctrineMessage = $messageEntity->toEntity($message);
// Access stored recipients
echo $doctrineMessage->getTo(); // [email protected]
print_r($doctrineMessage->getCc()); // ['[email protected]', '[email protected]']
print_r($doctrineMessage->getBcc()); // ['[email protected]']
print_r($doctrineMessage->getReplyTo()); // ['[email protected]']use Nette\Mail\Message;
$message = new Message;
$message->setPriority(Message::HIGH); // HIGH, NORMAL, or LOW
$doctrineMessage = $messageEntity->toEntity($message);
echo $doctrineMessage->getPriority(); // 1 (HIGH)After successfully sending an email or when no longer needed:
// Remove attachment files for a specific message
$messageEntity->invalidAttachmentStorage($doctrineMessage);// Set custom directory permissions (default is 0777)
$messageEntity->setDefaultAttachmentDirectoryMode(0755);The library automatically injects a hidden tracking token into HTML emails when converting from entity to message:
<div style="color:white;font-size:1pt" id="pair__token">42_2024-01-15</div>This token contains the message ID and date, enabling:
- Email open tracking (when combined with tracking pixel)
- Pairing sent emails with responses
- Email delivery verification
The entity creates the following table structure:
CREATE TABLE core__email_message (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`from` VARCHAR(255) NOT NULL,
`to` VARCHAR(255) NOT NULL,
subject VARCHAR(255) NOT NULL,
html_body LONGTEXT,
text_body LONGTEXT,
cc JSON NOT NULL,
bcc JSON NOT NULL,
reply_to JSON NOT NULL,
return_path VARCHAR(255),
priority SMALLINT NOT NULL DEFAULT 3,
attachments JSON NOT NULL,
INDEX core__email_message_subject (id, subject)
);The library provides clear error messages for common issues:
- Missing From Address: Triggers error in web context, throws exception in CLI
- Missing Recipient: Triggers warning for potential issues
- Invalid Attachment Path: Throws
RuntimeExceptionor logs via PSR-3 logger - Missing Temp Directory: Throws
RuntimeExceptionwith configuration hints
Run static analysis:
composer phpstanJan Barรกลกek
- Website: https://baraja.cz
- GitHub: https://github.com/baraja-core
baraja-core/doctrine-mail-message is licensed under the MIT license. See the LICENSE file for more details.