Jump to content

Idea and proof of concept: Mailer class


teppo
 Share

Recommended Posts

So, I've been seeing some email-related topics around here and actually had quite a few struggles of my own with this very subject myself lately.

Thing is that sending email should be easy, but it's not always that; especially for those who have to work on multiple, low-price (and regrettably often low-quality) platforms that may or may not provide proper mail servers.. or prefer to host their services themselves and still want to avoid setting up and maintaining a mail server. Hosting a mail server can be real pain in the ass when things don't work like they should, not to mention that most people have very little knowledge about DNS entries etc. this requires.

Anyway, long story short: yesterday I started thinking that wouldn't it be sweet to have a layer of abstraction within ProcessWire for sending email? Of course one could still use PHP mail() -- there's no way and no sense in even trying to stop that -- but using a common gateway would definitely bring in some extra value.

This layer I'm talking about could by default use built-in PHP mail() but also make it possible to override it, thus allowing multitude of options that PHP mail(), being bound to Sendmail / it's alternatives, can't offer without additional server-side software (such as Nullmailer.)

By making sending emails hookable it could also enable all kinds of interesting tricks to be done when mail is sent -- such as writing a custom log file, sending another email to someone else, updating local content (I'd imagine that this could be useful for building newsletter platform, for an example) and so on.

Since words tend to fail me at times like these, I put together a quick proof of concept of what I'm talking about here, accompanied by one example of what could be achieved by doing this:

  • A very simple yet functional Mailer class
  • Two commits on top here list all the changes I've made in my PW fork to make this work -- including the fact that I've altered some default modules to use $mailer->send() instead of mail()
  • SwiftMailer module, again very simple but fully functional (though only tested with Gmail SMTP) drop-in replacement for PHP mail()

So, what do you folks think of this? Please keep in mind that this is just a suggestion and I'm not saying that this is the right path to take especially considering that it would add another API variable -- it just felt like best option here and I couldn't think of cleaner way to achieve it.

  • Like 14
Link to comment
Share on other sites

I like it! There is no better way to propose ideas than this Teppo. 

First: Yes, simple wrapper is definitely needed. I think it should take same params than mail() does - and just like your proposal works. 

What I am not sure is that if replace hook is way to go here though? Maybe having general config module (or just config.php) where one could select which mailer is used? Also - not sure about this one - but sometimes one might want to set mailer on code level, something like this:

$postmark = $modules->get("MailerPostmark");

$mailer->provider = $postmark;

$mailer->send(...);

That would allow to having multiple provider modules installed and still having control which one get's used (and possibility to use them in different parts of the application).

Having this supported in core there wouldn't be any reason not to build newsletter system in PW... :)

  • Like 5
Link to comment
Share on other sites

What I am not sure is that if replace hook is way to go here though? Maybe having general config module (or just config.php) where one could select which mailer is used? Also - not sure about this one - but sometimes one might want to set mailer on code level, something like this:

$postmark = $modules->get("MailerPostmark");

$mailer->provider = $postmark;

$mailer->send(...);

Agreed. This is something I thought of too.. right after posting that original topic :)

I haven't really had the need to switch mailer "on the fly" before (especially when using Swift Mailer, which has always been pretty damn effective at sending to multiple recipients / batch sending emails etc. out of the box) which is also why I considered replace best method here. This way once an alternative mailer module is installed and configured it just magically takes over and developer doesn't even need to know that anything has changed (other than the fact that suddenly Mailer has awesome super powers.)

On the other hand, I could imagine that in some cases (such as when sending those newsletters..) one might definitely want to switch to another provider -- perhaps even a web service like Mailchimp or Campaign Monitor. For this reason alone it would make a lot of sense to have Mailer configurable at code level. There would still be multiple ways to approach this need and I don't think any of them would need to eliminate the ability to create those "drop-in replacement modules":

// like posted above ...
$postmark = $modules->get("MailerPostmark");
$mailer->provider = $postmark;
$mailer->send(...);

// ... or you could also init another Mailer!
$myMailer = new Mailer("MailerPostmark");
  • Like 1
Link to comment
Share on other sites

  • 9 months later...

This topic didn't get too much action earlier, but I do think something along these lines is definitely needed. I would love to send all PW-mails through mailgun or similar service, or at least smtp.

Ryan and others, do you see any drawbacks in Teppo's approach?

Link to comment
Share on other sites

I'd definitely like to see this. I use SwiftMailer at the moment and love its object orientated approach over php's mail(). I send most of my mail through Mandrill or Mailgun. I currently use SMTP but it would be nice to have transports that send via their APIs as these offer a few more options. It would also be a really easy route for ProcessWire to receive mail in a standardised manner - you ust provide an enpoint for their webhooks and a hookable method for consuming them.

  • Like 1
Link to comment
Share on other sites

I love the idea of this. I'm getting to grips with sending most important email through Mandrill for web applications now as you can see some nice stats and handle bounces well with their API, so if there was a sensible way of overriding the default email functionality with a class like is being talked about above that would be great.

Glancing up this thread, it looks like we would have MailerSwiftMailer, MailerPostmark and MailerMandrill in a short space of time.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...