Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Mailing Bundle Laravel Package

creonit/mailing-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require creonit/mailing-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        Creonit\MailingBundle\CreonitMailingBundle::class => ['all' => true],
    ];
    
  2. Configuration: Add the bundle config to config/packages/creonit_mailing.yaml:

    creonit_mailing:
        from: 'noreply@example.com'
        base_template: 'mail/base.html.twig'
        templates_path: '%kernel.project_dir%/templates/mailing'
    
  3. First Use Case: Create a template file at templates/mailing/welcome.yaml:

    welcome:
        title: 'Welcome Email'
        subject: 'Welcome to Our Platform'
        template: '<p>Hello {{ name }}, welcome!</p>'
    

    Send the email in a controller:

    use Creonit\MailingBundle\MailingService;
    
    public function sendWelcome(MailingService $mailingService)
    {
        $mailingService->send('welcome', ['name' => 'John Doe']);
    }
    

Implementation Patterns

Template Management

  • YAML Templates: Store reusable email templates in YAML files under templates_path (e.g., welcome.yaml, invoice.yaml). Use Twig syntax for dynamic content:

    invoice:
        subject: 'Your Invoice #{{ invoice_number }}'
        template: 'Invoice details: {{ items|join(", ") }}'
    
  • Globals: Define reusable variables in config/packages/creonit_mailing.yaml under globals:

    creonit_mailing:
        globals:
            app_name: 'MyApp'
            support_email: 'support@example.com'
    

    Access them in templates via {{ globals.app_name }}.

  • Dynamic Context: Pass context data when sending emails:

    $mailingService->send('welcome', [
        'name' => 'Alice',
        'user_id' => 123,
    ]);
    

Integration with Laravel

  • Service Integration: Bind the MailingService to Laravel’s container in config/services.php:

    'mailing' => Creonit\MailingBundle\MailingService::class,
    

    Inject it into controllers/services:

    public function __construct(private MailingService $mailingService) {}
    
  • Event-Driven Emails: Trigger emails from events (e.g., user registration):

    use Symfony\Component\EventDispatcher\EventDispatcherInterface;
    
    public function register(UserRegisteredEvent $event, EventDispatcherInterface $dispatcher)
    {
        $dispatcher->dispatch(new SendWelcomeEmailEvent($event->getUser()));
    }
    

    Listen for the event in a subscriber:

    public function onSendWelcomeEmail(SendWelcomeEmailEvent $event, MailingService $mailingService)
    {
        $mailingService->send('welcome', ['name' => $event->getUser()->name]);
    }
    
  • Queueing Emails: Use Laravel’s queue system to defer email sending:

    $mailingService->sendLater('welcome', ['name' => 'Bob'], now()->addMinutes(5));
    

Customization

  • Template Loaders: Extend AbstractTemplateLoader to load templates from custom sources (e.g., database, API):

    class DatabaseTemplateLoader extends AbstractTemplateLoader
    {
        public function load(TemplateCollection $collection)
        {
            $templates = $this->fetchFromDatabase();
            foreach ($templates as $template) {
                $mailingTemplate = new MailingTemplate($template['name']);
                $mailingTemplate->setSubject($template['subject']);
                $mailingTemplate->setTemplate($template['body']);
                $collection->add($mailingTemplate);
            }
        }
    }
    

    Register the loader in config/packages/creonit_mailing.yaml:

    creonit_mailing:
        template_loaders:
            - Creonit\MailingBundle\Templating\Loader\DatabaseTemplateLoader
    
  • Message Builders: Customize email construction (e.g., add attachments, set reply-to):

    class AttachmentMessageBuilder implements MessageBuilderInterface
    {
        public function build(MailingTemplate $template, array $context): MailingMessage
        {
            $message = new MailingMessage();
            $message->setSubject($template->getSubject());
            $message->setTemplate($template->getTemplate());
            $message->addAttachment($context['attachment_path']);
            return $message;
        }
    }
    

    Register the builder in config/packages/creonit_mailing.yaml:

    creonit_mailing:
        message_builder: Creonit\MailingBundle\Message\AttachmentMessageBuilder
    

Gotchas and Tips

Pitfalls

  • Template Paths: Ensure templates_path in the config points to an existing, writable directory. Defaults to config/mailing_templates, but Laravel’s templates directory is more conventional. Fix: Update templates_path to %kernel.project_dir%/templates/mailing.

  • Caching Templates: The bundle caches templates by default. Clear the cache after adding new templates:

    php bin/console cache:clear
    

    Tip: Disable caching in development:

    creonit_mailing:
        cache_templates: false
    
  • Twig Extensions: If using custom Twig functions/filters in templates, ensure they’re registered with Twig:

    $twig->addExtension(new MyCustomTwigExtension());
    

    Tip: Extend the bundle’s Twig environment in a compiler pass.

  • Context Overrides: Template variables can be overridden by context data. If {{ name }} is missing in the context but exists in globals, it will use the global value. Tip: Explicitly pass required context data to avoid runtime errors.

Debugging

  • Template Errors: Enable Twig’s strict variables to catch undefined variables:

    twig:
        strict_variables: true
    

    Tip: Use {{ dump(context) }} in templates to inspect passed data.

  • Logging: Enable debug mode to log template loading and email sending:

    creonit_mailing:
        debug: true
    

    Check logs at var/log/dev.log.

  • Missing Templates: If a template isn’t found, verify:

    1. The YAML file exists in templates_path.
    2. The template name matches the key in the YAML file (e.g., welcome in welcome.yaml).
    3. The file has valid YAML syntax.

Extension Points

  • Custom Mailers: Replace the default Swiftmailer integration by binding a custom mailer service:

    $container->bind(MailingService::class)->to(MyCustomMailingService::class);
    
  • Template Validation: Add validation for template fields (e.g., required subject or template):

    class ValidatingTemplateLoader extends AbstractTemplateLoader
    {
        public function load(TemplateCollection $collection)
        {
            $templates = $this->loadTemplatesFromSource();
            foreach ($templates as $template) {
                if (empty($template['subject'])) {
                    throw new \InvalidArgumentException('Subject is required.');
                }
                // ...
            }
        }
    }
    
  • Internationalization: Support multi-language emails by dynamically setting subject and template based on locale:

    # templates/mailing/welcome.en.yaml
    welcome:
        subject: 'Welcome (English)'
        template: 'Hello {{ name }}!'
    
    # templates/mailing/welcome.fr.yaml
    welcome:
        subject: 'Bienvenue (French)'
        template: 'Bonjour {{ name }}!'
    

    Tip: Use a custom template loader to switch templates based on the current locale.

  • Testing: Mock the MailingService in PHPUnit tests:

    $mailingService = $this->createMock(MailingService::class);
    $mailingService->expects($this->once())
        ->method('send')
        ->with('welcome', ['name' => 'Test User']);
    $this->app->instance(MailingService::class, $mailingService);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware