kikwik / mail-manager-bundle
Transactional email manager for symfony 6.4 / 7.*
Installs: 2
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Type:symfony-bundle
pkg:composer/kikwik/mail-manager-bundle
Requires
- php: >=8.2
- doctrine/orm: ^2.19|^3.0
- ehyiah/ux-quill: ^3.0
- symfony/framework-bundle: ^6.4|^7.0
- symfony/mailer: ^6.4|^7.0
- twig/twig: ^3.0
This package is auto-updated.
Last update: 2025-10-28 09:19:49 UTC
README
The KikwikMailManagerBundle is a Symfony bundle that manages transactional emails for symfony 6.4 / 7.*.
Installation
Make sure Composer is installed globally, as explained in the installation chapter of the Composer documentation.
- Open a command console, enter your project directory and execute:
$ composer require kikwik/mail-manager-bundle
Configuration
- Create your Entity class that extends
Kikwik\MailManagerBundle\Model\Template. The staticgetTemplateChoicesmethod can be used to list the available templates defined in the system (inside the easyadmin controllers)
<?php namespace App\Entity\Mail; use App\Repository\Mail\MailTemplateRepository; use Doctrine\ORM\Mapping as ORM; use Gedmo\Blameable\Traits\BlameableEntity; use Gedmo\IpTraceable\Traits\IpTraceableEntity; use Gedmo\Timestampable\Traits\TimestampableEntity; use Kikwik\MailManagerBundle\Model\Template; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity(repositoryClass: MailTemplateRepository::class)] #[ORM\Table('mail__template')] #[UniqueEntity(fields: ['name'])] class MailTemplate extends Template { use TimestampableEntity; use BlameableEntity; use IpTraceableEntity; /**************************************/ /* CONST for template choices */ /**************************************/ const MODEL1 = '01-model1'; const MODEL2 = '02-model2'; public static function getTemplateChoices(): array { return [ 'Model of type 1' => self::MODEL1, 'Model of type 2' => self::MODEL2, ]; } /**************************************/ /* PROPERTIES */ /**************************************/ #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; /**************************************/ /* GETTERS & SETTERS */ /**************************************/ public function getId(): ?int { return $this->id; } }
- (optional) Create your Entity class that extends
Kikwik\MailManagerBundle\Model\Decorator:
<?php namespace App\Entity\Mail; use App\Repository\Mail\MailDecoratorRepository; use Doctrine\ORM\Mapping as ORM; use Gedmo\Blameable\Traits\BlameableEntity; use Gedmo\IpTraceable\Traits\IpTraceableEntity; use Gedmo\Timestampable\Traits\TimestampableEntity; use Kikwik\MailManagerBundle\Model\Decorator; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; #[ORM\Entity(repositoryClass: MailDecoratorRepository::class)] #[ORM\Table('mail_decorator')] #[UniqueEntity(fields: ['name'])] class MailDecorator extends Decorator { use TimestampableEntity; use BlameableEntity; use IpTraceableEntity; /**************************************/ /* PROPERTIES */ /**************************************/ #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; /**************************************/ /* GETTERS & SETTERS */ /**************************************/ public function getId(): ?int { return $this->id; } }
- Create your Entity class that extends
Kikwik\MailManagerBundle\Model\Log:
<?php namespace App\Entity\Mail; use App\Repository\Mail\MailLogRepository; use Doctrine\ORM\Mapping as ORM; use Gedmo\Blameable\Traits\BlameableEntity; use Gedmo\IpTraceable\Traits\IpTraceableEntity; use Gedmo\Timestampable\Traits\TimestampableEntity; use Kikwik\MailManagerBundle\Model\Log; #[ORM\Entity(repositoryClass: MailLogRepository::class)] #[ORM\Table('mail__log')] class MailLog extends Log { use TimestampableEntity; use BlameableEntity; use IpTraceableEntity; /**************************************/ /* PROPERTIES */ /**************************************/ #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; /**************************************/ /* GETTERS & SETTERS */ /**************************************/ public function getId(): ?int { return $this->id; } }
- Configure the bundle in
config/packages/kikwik_mail_manager.yaml:
kikwik_mail_manager: template_class: App\Entity\Mail\MailTemplate decorator_class: App\Entity\Mail\MailDecorator log_class: App\Entity\Mail\MailLog
- Update the database to create the tables for entities provided by the bundle:
$ php bin/console make:migration $ php bin/console doctrine:migrations:migrate
Usage
Autowire the Kikwik\MailManagerBundle\Service\MailBuilderFactory service and call the createMailBuilder method,
then use the returned Kikwik\MailManagerBundle\Service\MailBuilder object to compose emails.
Autowire the Kikwik\MailManagerBundle\Service\MailManager service to send emails.
use App\Entity\Mail\MailTemplate; use Symfony\Component\Mime\Address; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Kikwik\MailManagerBundle\Service\MailBuilderFactory; use Kikwik\MailManagerBundle\Service\MailSender; final class MyController extends AbstractController { public function myAction(MailBuilderFactory $mailBuilderFactory, MailSender $mailSender) { // Example 1 - create, send and persist if($mailBuilder = $mailBuilderFactory->createMailBuilder(MailTemplate::MODEL1)) // MailBuilderFactory will be null if the template does not exists or is not enabled { // create the Log object $mailLog = $mailBuilder ->context(['attivazione'=>$richiesta]) // set context ->to([new Address('sales@customer.com','My customer')]) // set to ->cc(['info@customer.com']) // set cc ->bcc(['admin@mycompany.com', 'helpdesk@mycompany.com']) // set bcc ->getLog() ; $mailLog->setSomethingCustom($myObject); // $mailLog is your App\Entity\Mail\MailLog entity, you can set your custom property $mailSender ->send($mailLog) // send the email, persist the $mailLog and flush ; } // Example 2 - persist the log without send email for later review if($mailBuilder = $mailBuilderFactory->createMailBuilder(MailTemplate::MODEL1)) { // create the Log object $mailLog = $mailBuilder ->context(['attivazione'=>$richiesta]) ->to([new Address('sales@customer.com','My customer')]) ->getLog() ; $mailSender ->needManualReview($mailLog) // mark the Log object as "need manual review", persist and flush ; } // Example 3 - persist the log without send email for archive if($mailBuilder = $mailBuilderFactory->createMailBuilder(MailTemplate::MODEL1)) { // create the Log object $mailLog = $mailBuilder ->context(['attivazione'=>$richiesta]) ->to([new Address('sales@customer.com','My customer')]) ->getLog() ; $mailSender ->doNotSend($mailLog) // mark the Log object as "do not send", persist and flush ; } // Example 4 - send email without persist the log if($mailBuilder = $mailBuilderFactory->createMailBuilder(MailTemplate::MODEL1)) { // create the Log object $mailLog = $mailBuilder ->context(['attivazione'=>$richiesta]) ->to([new Address('sales@customer.com','My customer')]) ->getLog() ; $mailSender->send($mailLog, false); // send the email without saving the Log object in the database thanks to the second false parameter } } }
EasyAdmin
You can use the Kikwik\MailManagerBundle\EasyAdmin\KikwikMailLogCrudControllerTrait
and Kikwik\MailManagerBundle\EasyAdmin\KikwikMailTemplateCrudControllerTrait
and Kikwik\MailManagerBundle\EasyAdmin\KikwikMailDecoratorCrudControllerTrait
to add a custom crud controller for MailLog and MailTemplate and MailDecorator entities:
<?php namespace App\Controller\Admin\Mail; use App\Entity\Mail\MailTemplate; use EasyCorp\Bundle\EasyAdminBundle\Config\Filters; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use Kikwik\MailManagerBundle\EasyAdmin\KikwikMailTemplateCrudControllerTrait; class MailTemplateCrudController extends AbstractCrudController { use KikwikMailTemplateCrudControllerTrait; public static function getEntityFqcn(): string { return MailTemplate::class; } public function configureFields(string $pageName): iterable { return $this->getDefaultFieldList(MailTemplate::getTemplateChoices()); } public function configureFilters(Filters $filters): Filters { return $this->addDefaultFilters($filters); } }
<?php namespace App\Controller\Admin\Mail; use App\Entity\Mail\MailDecorator; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use Kikwik\MailManagerBundle\EasyAdmin\KikwikMailDecoratorCrudControllerTrait; class MailDecoratorCrudController extends AbstractCrudController { use KikwikMailDecoratorCrudControllerTrait; public static function getEntityFqcn(): string { return MailDecorator::class; } public function configureFilters(Filters $filters): Filters { return $this->addDefaultFilters($filters); } }
<?php namespace App\Controller\Admin\Mail; use App\Entity\Mail\MailLog; use App\Entity\Mail\MailTemplate; use EasyCorp\Bundle\EasyAdminBundle\Config\Filters; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use Kikwik\MailManagerBundle\EasyAdmin\KikwikMailLogCrudControllerTrait; class MailTemplateCrudController extends AbstractCrudController { use KikwikMailLogCrudControllerTrait; public static function getEntityFqcn(): string { return MailLog::class; } public function configureFields(string $pageName): iterable { return $this->getDefaultFieldList(); } public function configureFilters(Filters $filters): Filters { return $this->addDefaultFilters($filters, MailTemplate::getTemplateChoices()); } protected function cloneLogCustomFields(Log $oldLog, Log $newLog): void { $newLog->setSomethingCustom($oldLog->getSomethingCustom()); // set a custom property when cloning the log for forward action } }