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

Swiftmailerdbbundle Laravel Package

appventus/swiftmailerdbbundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require appventus/swiftmailerdbbundle:dev-master
    

    Add to AppKernel.php:

    new AppVentus\SwiftMailerDBBundle\AppVentusSwiftMailerDBBundle(),
    
  2. Configure config.yml:

    white_october_swift_mailer_db:
        entity_class: App\Entity\MailMessage
    swiftmailer:
        spool:
            type: db
    
  3. Create a Doctrine Entity: Extend EmailInterface and define a status field (e.g., sent, queued):

    use AppVentus\SwiftMailerDBBundle\Model\EmailInterface;
    
    #[ORM\Entity]
    class MailMessage implements EmailInterface
    {
        #[ORM\Column(type: 'string', length: 255)]
        private $status;
    }
    
  4. First Use Case: Send an email via SwiftMailer (e.g., in a controller):

    $message = (new \Swift_Message('Hello'))
        ->setFrom('from@example.com')
        ->setTo('to@example.com')
        ->setBody('Test email');
    $this->get('mailer')->send($message);
    

    The email will now be stored in your database (check MailMessage table).


Implementation Patterns

Core Workflow

  1. Database Spooling:

    • All emails are stored in the configured entity (e.g., MailMessage) before sending.
    • Useful for:
      • Debugging (review unsent emails).
      • Retrying failed sends.
      • Analytics (track email volume/metrics).
  2. SMS Support (Limited):

    • The bundle claims SMS support, but implementation is undocumented.
    • Workaround: Extend the entity to include SMS-specific fields (e.g., recipientPhone, smsBody) and manually handle sending via a gateway (e.g., Twilio).
  3. Queue Processing:

    • Use a cron job or Symfony messenger to process queued emails:
      php bin/console swiftmailer:spool:send --env=prod
      
    • For async processing, integrate with Symfony Messenger or a queue worker (e.g., Laravel Horizon equivalent).
  4. Entity Customization:

    • Extend EmailInterface to add custom fields:
      #[ORM\Column(type: 'datetime', nullable: true)]
      private $sentAt;
      
      #[ORM\Column(type: 'string', length: 255, nullable: true)]
      private $trackingId;
      
    • Override bundle services to inject custom logic (e.g., logging, validation).
  5. SwiftMailer Integration:

    • Use the bundle’s SwiftMailer service directly:
      $mailer = $this->get('mailer');
      $mailer->send($message); // Spooled to DB.
      

Advanced Patterns

  1. Bulk Sending:

    • Fetch queued emails in batches and send them programmatically:
      $em = $this->getDoctrine()->getManager();
      $emails = $em->getRepository(MailMessage::class)
          ->findBy(['status' => 'queued'], ['createdAt' => 'ASC'], 50);
      foreach ($emails as $email) {
          $swiftMessage = $this->convertEntityToSwiftMessage($email);
          $this->get('mailer')->send($swiftMessage);
          $email->setStatus('sent');
          $em->flush();
      }
      
  2. Event Listeners:

    • Listen to swiftmailer.send events to log or modify emails:
      // src/EventListener/SwiftMailerListener.php
      public function onSend(SendEvent $event)
      {
          $message = $event->getMessage();
          // Custom logic (e.g., add headers, validate recipients).
      }
      
      Register in services.yml:
      services:
          App\EventListener\SwiftMailerListener:
              tags:
                  - { name: kernel.event_listener, event: swiftmailer.send, method: onSend }
      
  3. Testing:

    • Mock the spooler in tests to avoid real sends:
      $this->container->set('swiftmailer.transport.real', $this->createMock(SpoolTransport::class));
      
    • Assert emails were queued:
      $this->assertCount(1, $this->getDoctrine()->getRepository(MailMessage::class)->findAll());
      

Gotchas and Tips

Pitfalls

  1. Deprecated Bundle:

    • Last updated in 2017 for Symfony 2. No Laravel compatibility.
    • Mitigation: Use as a reference; adapt logic to Laravel’s SwiftMailer + Doctrine integration.
  2. SMS Support Ambiguity:

    • The README lacks details on SMS implementation.
    • Workaround: Manually handle SMS via a separate service (e.g., SmsGateway) and store SMS records in a parallel entity.
  3. Entity Requirements:

    • The status field is mandatory but not enforced by the bundle.
    • Fix: Add validation in your entity:
      #[Assert\NotBlank]
      #[ORM\Column(type: 'string', length: 255)]
      private $status;
      
  4. Spool Processing:

    • The swiftmailer:spool:send command may fail silently if the spool is misconfigured.
    • Debug: Check logs and verify the type: db setting in config.yml.
  5. Performance:

    • Large email volumes may slow down your app.
    • Optimization: Use Doctrine batch operations or a queue system (e.g., RabbitMQ).

Debugging Tips

  1. Check the Spool:

    • Query your MailMessage table to verify emails are stored:
      SELECT * FROM mail_message WHERE status = 'queued';
      
  2. Enable SwiftMailer Debug:

    • Add to config.yml:
      swiftmailer:
          debug: true
      
    • Check logs for spooling errors.
  3. Doctrine Events:

    • Listen for prePersist/preUpdate to debug entity changes:
      $em->getEventManager()->addEventListener(
          [ORM\Events::prePersist, ORM\Events::preUpdate],
          function ($event) {
              error_log('MailMessage change:', $event->getEntity());
          }
      );
      

Extension Points

  1. Custom Spooler:

    • Extend the bundle’s DBTransport class to add features (e.g., soft deletes):
      class CustomDBTransport extends DBTransport
      {
          public function send(Swift_Message $message, &$failedRecipients = null)
          {
              // Add custom logic (e.g., rate limiting).
              parent::send($message, $failedRecipients);
          }
      }
      
    • Register in services.yml:
      services:
          swiftmailer.transport.db:
              class: App\SwiftMailer\CustomDBTransport
              arguments: ['@doctrine.orm.entity_manager']
              tags:
                  - { name: swiftmailer.transport }
      
  2. Add Retry Logic:

    • Extend the entity to track failed attempts:
      #[ORM\Column(type: 'integer', nullable: true)]
      private $failedAttempts;
      
      #[ORM\Column(type: 'datetime', nullable: true)]
      private $lastFailure;
      
    • Implement a retry mechanism in a cron job.
  3. Laravel Adaptation:

    • Replace Symfony’s SwiftMailerBundle with Laravel’s swiftmailer package.
    • Use Laravel’s service provider to bind the custom spooler:
      // app/Providers/AppServiceProvider.php
      public function register()
      {
          $this->app->bind(
              Swift_Transport::class,
              function () {
                  return new CustomDBTransport(
                      app('db')->connection()->getDoctrineSchemaManager()
                  );
              }
          );
      }
      
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