Install Dependencies
Run composer require braune-digital/mail-bundle and ensure doctrine/orm, sonata-project/easy-extends, and braune-digital/translation-base-bundle are installed.
Verify SonataAdmin is installed if backend management is needed.
Enable Bundles
Add to config/bundles.php (or AppKernel.php for Symfony <5.0):
BrauneDigital\TranslationBaseBundle\BrauneDigitalTranslationBaseBundle::class,
BrauneDigital\MailBundle\BrauneDigitalMailBundle::class,
Generate Extensions Run:
php bin/console sonata:easy-extends:generate --dest=src BrauneDigitalMailBundle
Enable the extended bundle in config/bundles.php:
Application\BrauneDigital\MailBundle\BrauneDigitalMailBundle::class,
Configure
Add to config/packages/braune_digital_mail.yaml:
braune_digital_mail:
user_class: App\Entity\User
base_template_path: "%kernel.project_dir%/templates/emails"
First Use Case
Create a template file (e.g., welcome.txt.twig) in templates/emails/ and reference it in a controller:
use BrauneDigital\MailBundle\Mailer\MailerService;
class MailController extends AbstractController {
public function sendWelcome(MailerService $mailer) {
$mailer->send('welcome', 'user@example.com', ['name' => 'John']);
}
}
Template Management
templates/emails/ (e.g., welcome.html.twig, welcome.txt.twig).{# templates/emails/welcome.html.twig #}
<h1>Hello, {{ name }}!</h1>
Sending Emails
MailerService into controllers/services:
$mailer->send(
'welcome', // Template name (without extension)
'recipient@example.com',
['name' => 'Alice'], // Variables
['subject' => 'Welcome!'] // Optional overrides
);
$mailer->sendWithAttachment('invoice', 'user@example.com', [], [
'attachments' => ['/path/to/file.pdf' => 'invoice.pdf']
]);
Translations
BrauneDigitalTranslationBaseBundle for multi-language templates.translations/emails/ (e.g., welcome.en.yml):
welcome:
subject: "Welcome, {{ name }}!"
SonataAdmin Integration
Mail > Templates.Dynamic Recipients
$users = $entityManager->getRepository(User::class)->findAll();
foreach ($users as $user) {
$mailer->send('newsletter', $user->getEmail(), ['user' => $user]);
}
Event Listeners Trigger emails on entity events (e.g., user registration):
// src/EventListener/RegistrationListener.php
public function onRegistration(RegistrationEvent $event) {
$mailer->send('welcome', $event->getUser()->getEmail(), ['name' => $event->getUser()->getName()]);
}
Queueing Emails Use Symfony Messenger to defer email sending:
$message = new SendMailMessage('welcome', 'user@example.com', ['name' => 'Bob']);
$bus->dispatch($message);
Testing
Mock MailerService in tests:
$mailer = $this->createMock(MailerService::class);
$mailer->expects($this->once())
->method('send')
->with('welcome', 'test@example.com', ['name' => 'Test']);
Template Path Configuration
base_template_path in config will cause Twig\Error\LoaderError.%kernel.project_dir%/templates/emails).Caching Issues
php bin/console cache:clear
SonataAdmin Dependencies
SonataEasyExtends and SonataAdmin for backend features.Translation Overrides
{{ name }}) in translations may not render if the variable isn’t passed.send() call.User Class Mismatch
user_class in config doesn’t match your actual user entity, the admin panel may fail.App\Entity\User).Check Logs
Enable debug mode (APP_DEBUG=true) to log template loading errors:
php bin/console debug:config braune_digital_mail
Template Not Found If a template isn’t found, check:
welcome.html.twig, not welcome.twig).base_template_path is correct.SonataAdmin Permissions
Ensure the user has access to the Mail admin section in Sonata.
Custom Mailer
Extend MailerService to add logic (e.g., logging, analytics):
class CustomMailerService extends MailerService {
public function send(string $template, string $to, array $vars = [], array $options = []) {
// Add custom logic (e.g., track sends)
parent::send($template, $to, $vars, $options);
}
}
Dynamic Template Selection Override template selection logic in a custom service:
$mailer->setTemplateResolver(new CustomTemplateResolver());
Add Fields to Admin Extend the Sonata admin class to add custom fields:
// src/Admin/MailTemplateAdmin.php
protected function configureFormFields(FormMapper $formMapper) {
$formMapper->add('custom_field', 'text');
}
Hook into Email Events Dispatch events before/after sending:
$mailer->onSend(function (SendMailEvent $event) {
// Log or modify the email
});
Precompile Templates
Use twig:compile to precompile templates for faster rendering:
php bin/console twig:compile
Batch Processing For bulk emails, use chunking to avoid memory issues:
$users = $entityManager->getRepository(User::class)->findAll();
array_chunk($users, 100, function ($chunk) use ($mailer) {
foreach ($chunk as $user) {
$mailer->send('newsletter', $user->getEmail(), ['user' => $user]);
}
});
How can I help you explore Laravel packages today?