Code Monkey home page Code Monkey logo

conceptmailbundle's Introduction

Mail Bundle

This is a heavily forked project from https://github.com/extellient/MailBundle which now only bears similarity in some of the Interfaces. The main changes were to upgrade to use symfony/mail, to remove Doctrine as a Sending Strategy, to switch to using MailTemplate and to allow building of the mail template ahead of time.

This Bundle has been uploaded because someone asked to see how I modified the underlying fork. Use this at your own discretion. It is not a plug-and-play bundle and would require manual drop-in.

What are Changes Made in This Bundle compared to the MailBundle

  1. Because I didn't intend to use this as a Bundle, (I knew I'd need more modifications) I updated the Entity namespaces and moved some of the interfaces around to suit my project https://github.com/Kalyse/ConceptMailBundle/tree/master/Entity

  2. Internally, my application sends Mails based on Events which are sent. ie. If a Guest makes a reservation for a booking/property, there is a "ReservationCreatedEvent" which is dispatched. I decided to create subs for all mail that are sent. https://github.com/Kalyse/ConceptMailBundle/blob/master/Mail/EventSubscriber/ReservationGuestConfirmationSubscriber.php

  3. I changed the method signature responsible for sending mail. I prefer

$message = $this->mailer->createTemplatedEmail(
    $template->getCode(),
    $mail,
    $variables
);

$this->mailer->send($message);
  1. The idea here is that we pass a template code, something like foo-bar-template, and the Template Code is fetched from the database.

For example, a mail_template might look like:

insert into symfony.mail_template (id, owner_id, channel_id, created_at, updated_at, mail_subject, mail_body, code)
values (null, null, null, '2021-01-16 14:41:27', null, 'You have received a new booking.',
        '@Mails/reservationStakeholderCreated.html.twig', 'reservation-stakeholder');

The changes I made were to associate a template with a "User" and some domain specific relationship called a "Channel" (which you don't need to know about).

Because I didn't want raw twig templates storing in database, outside of version control, (unless they are user generator), I decided to allow paths to templates to be created.

  1. @Mails/reservationStakeholderCreated.html.twig is just a Twig namespace path to https://github.com/Kalyse/ConceptMailBundle/tree/master/Mail/templates I created a
twig:
    paths:
        # used in mail tempaltes paths like @Mail/foo.html.twig
        '%kernel.project_dir%/src/Mail/templates': Mails
  1. Added inky bundle for easier mail templating. https://github.com/foundation/inky

  2. In previous iterations of mail bundles I've created, I would store the serialized Entities used to send mail. This ended up meaning each mail could be 200kb+ in size just in storage for unused data which really didn't need to be stored. In this approach, I decided that I wanted to pass entities to a Mail Template, but then use my existing JMS serialize configuration to serialize and then flatted the structure into dot.notation.array.structure. You can see how https://github.com/Kalyse/ConceptMailBundle/blob/master/Mail/Template/VariableGenerator.php takes the variables and just returns a variable context which is then eventually passed to the Mail. We check to see if the object passed is capable of being managed through Doctrine (using isTransient) and then additionally, if an email is already passed, we can just wrap the email here. The reason why we do this: https://github.com/Kalyse/ConceptMailBundle/blob/master/Mail/Template/VariableGenerator.php#L62 is because I wanted to take advantage of this method https://github.com/symfony/symfony/blob/5.x/src/Symfony/Bridge/Twig/Mime/WrappedTemplatedEmail.php#L38 so that I can embed images in my emails... such as https://github.com/Kalyse/ConceptMailBundle/blob/master/Mail/templates/snippets/reservationPayments.html.twig#L13

  3. Final change, eventually I need to be able to attach Mails which are sent to specific users, so we have a good log. Once a mail is sent it's stored in database, however, the previous bundle worked by:

    1. Configure Email Entity.

    2. Queue Email Entity ready for sending

    3. Run command which grabs all the mail from the Doctrine which haven't been sent.

I've been there before with other bundles which do this and the flexibility just lacks. I much prefer the following approach:

1. Create Mail Message 

2. Send to Symfony/Messenger

3. Save in Database as Entity

Doing things this way, means that you immediately have access to the Message rather than the other way around. Utilising symfony/messenger means you can still delegate sending to an async process as well, so there's just no reason to bundle up messages in database as a strategy.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.