Jump to content
teppo

Module: WireMailSwiftMailer

Recommended Posts

This module integrates Swift Mailer mailing library to ProcessWire, providing support for three different "transports" or methods of sending email: SMTP, Sendmail and Mail (essentially PHP's native mail() function).

WireMail is email-related base class for ProcessWire. See this post by Ryan for the details. Important thing to note here is that a) it's brand new, so as of this writing you'll need a fresh dev version of ProcessWire to use this and b) it makes integrating new ways of handling email-related tasks very easy.

Getting started

You can download or clone the module from GitHub: https://github.com/teppokoivula/WireMailSwiftMailer/.

Using this module is as simple as downloading / cloning it to your modules directory and installing it. If you're going to use SMTP or Sendmail features, insert correct SMTP credentials / Sendmail command to module settings first.

Third transport, Mail, is included simply because it's a native feature of Swift Mailer; if you're going to use it, I would suggest against installing this module. ProcessWire's native WireMail implementation handles this part just fine.

Basic usage

Sending emails should be done using wireMail() function -- if you use mail() directly, you're going to bypass ProcessWire's email handling features entirely. Main difference between mail() and wireMail() is the order and number of arguments:

$number_of_recipients = wireMail($to, $from, $subject, $body);

For more information please take a look at README.

This module is released under GPLv2 (just like ProcessWire itself) with the exception of included Swift Mailer library, which is copyright © Fabien Potencier and released under the MIT license.

  • Like 20

Share this post


Link to post
Share on other sites

This is fantastic teppo!

I don't necessarily think you should (as it may make the module unnecessarily complex), but do you have any plans to implement any of the SwiftMailer plugins like Decorator, AntiFlood, and Throttler? I use these for sending out bulk emails to subscribers.

I think perhaps in these cases it is simpler if we just include swiftmailer separately in the appropriate template/module code, but thought I'd raise it in case you have any ideas along these lines.

  • Like 1

Share this post


Link to post
Share on other sites

@adrian: I browsed through the plugins just today, wondering if (and how) some of those should be implemented. Not sure yet, but there's undeniably a lot of useful stuff there and it'd be shame not to put any of those in use.

One could always use wireMail() to return instance of WireMailSwiftMailer and it could, in turn, return instance of SwiftMailer.. though admittedly that's not so different from instantiating it yourself :)

  • Like 1

Share this post


Link to post
Share on other sites

Thanks Teppo, this is great! I'm looking forward to using this one. I did try to install but ran into some troubles. I was unable to get it to save SMTPServer or SMTPPort. I tracked that down to an issue with field dependencies (in the core, not your module). I've now fixed that in the core, but you may want to remove the requiredIf condition from those two fields if possible, at least temporarily, as I need to do more testing with the core changes I made before committing to GitHub. 

Once I was able to save the SMTPServer and SMTPPort settings, I tried to use the module but keep getting this message:

Fatal error: Class 'Swift_Message' not found in /Volumes/RyMain/Users/ryan/htdocs/cpi/site/modules/WireMailSwiftMailer/WireMailSwiftMailer.module on line 261

It looks like this condition is failing somehow: 

if ($this->transport != "Smtp" || $this->SMTPServer && $this->SMTPPort && $this->senderAddress) 

If I remove that line above (as well as the closing brace further in the function) then I no longer get errors. 

Following that, I configured it for Gmail per the instructions you linked to. The instructions said to choose "SSL/TLS". I chose "TLS" first, but that didn't work. So next I tried "SSL", and that worked. So SMTP setup is now working for me and it seems to work great.

Some other things to mention:

1. The module should not be autoload, if possible. WireMail is intended to be loaded on demand rather than on every request. 

2. The module should not be singular, if possible. When someone makes a call to wireMail(), we want to make sure we're returning them a brand new copy rather than one that might already have some email settings populated in it. That's why singular should be false, so that every time the module is retrieved a new instance is born.

3. The module version number shouldn't have preceding zeros, as this starts PHP thinking it's an octal number or something else (I don't recall). So version number should be 6 rather than 006. 

4. The require() statement in your init() function should likely be a require_once(), and it should ideally include the full path, just in case another copy of of the same directory name exists elsewhere in the PHP path. i.e. 

require_once(dirname(__FILE__) . '/Swift-' . self::SWIFT_VERSION . '/lib/swift_required.php'); 
  • Like 3

Share this post


Link to post
Share on other sites

@ryan: thanks, great suggestions!
 
I did notice the issue with saving settings, but had planned to reduce it to a proper test case and submit as an issue. Should've acted faster and disabled it right away, though, to avoid any unnecessary confusion  :)

Autoload and singular state were carried over from the original module, the intention of which was quite different from current implementation. I've taken care of these already, but will have to change the require logic you mentioned, as that admittedly no longer makes sense (and path part would've made sense even in the original form).

Once I was able to save the SMTPServer and SMTPPort settings, I tried to use the module but keep getting this message:

Fatal error: Class 'Swift_Message' not found in /Volumes/RyMain/Users/ryan/htdocs/cpi/site/modules/WireMailSwiftMailer/WireMailSwiftMailer.module on line 261
It looks like this condition is failing somehow: 
if ($this->transport != "Smtp" || $this->SMTPServer && $this->SMTPPort && $this->senderAddress) 
If I remove that line above (as well as the closing brace further in the function) then I no longer get errors.

So far I haven't been able to reproduce this. Will continue testing, though, since if it happened to you it's probably going to happen to others too. Shouldn't be too hard to figure out (*fingers crossed*).

3. The module version number shouldn't have preceding zeros, as this starts PHP thinking it's an octal number or something else (I don't recall). So version number should be 6 rather than 006.

I remember having problems remembering and "getting" the version number logic originally -- 006 was probably carried over from the time I first put this module together. Lately I've used integers, as that seems to be the expected thing there.

Slightly off-topic, perhaps, but integers still seem like a bad fit for version numbers to me. Version numbers should be able to go beyond 0-9 range.. and how do you represent versions such as 1.11.24 as an integer without actually using three sets of numbers?

Of course there's always the option of using strings in those cases, but I find it weird that integers are seen as "the default way" while they are only capable of representing some version numbers properly :)

  • Like 1

Share this post


Link to post
Share on other sites

So far I haven't been able to reproduce this. Will continue testing, though, since if it happened to you it's probably going to happen to others too. Shouldn't be too hard to figure out (*fingers crossed*).

Issue was quite obvious, actually: that "if" made sure that Swift Mailer wouldn't get initiated with SMTP transport unless it was properly configured. With the old logic this would've been fine, but not anymore, since local send() method is called regardless of whether Swift Mailer is available. Stupid mistake from me :)

I've changed this so that if you select SMTP transport but don't fill in required params (server and port), the module will fallback to Mail.

This (kind of) brings up another possible issue, though I'm not exactly sure how to deal with that yet: what to do when there's a connection issue in send()? Should that be caught and logged, should I throw an exception.. or is there even better alternative?

So far I'm thinking that an exception would be best way to handle this, so that apps / sites that rely on mail getting won't just continue like nothing happened.. though that might actually cause even more confusion.

Suggestions would be more than welcome :)

Share this post


Link to post
Share on other sites

@teppo: I think logging is mandatory, even if you throw an exception.

Also doing an automated fallback from SMTP to php-mail, without the users knowing isn't good in my opinion. Per default I would raise an error (and log it), but would give a configuration setting under advanced (or something) where the user have the possibility to enable that useful behave. If he check that option, _he_ has done so and not _you_, means he has at least be informed about that behave one times. :)

I'm a big fan of (automated) corrections for the user with missconfigurations, but with emails are a million possibilities given. Maybe on a company site they must use SMTP through a special company server to send company-internal messages, it could be that there are very restrictive settings and a mail from php-mail gets blocked and never reaching the recipients. (Sure, a rare case, but may be possible).

  • Like 4

Share this post


Link to post
Share on other sites

@horst: thanks for your input.. and your rare case is actually quite familiar for me, so I definitely get that :)

Fallback I mentioned earlier was actually intended as sort of an "installation helper", so that if you install the module on a server where PHP's mail() works (but you just don't want to use it or would prefer to use something else), it won't break anything. Running start, kind of.

Thinking about it now, a better solution for that might be setting the module to use Mail by default.. after that I could safely assume that if SMTP is selected but misconfigured, it's user error and exception should be thrown. This module can, after all, be used for Mail and Sendmail too, even though SMTP seems generally speaking most useful option and Mail definitely the least useful one..

Will have to give this some more thought, though. So far none of the options available seems to be clearly the best way to go. In any case you're definitely right in that it's not always possible (or even sensible for that matter) to attempt correcting mistakes user might've made.

  • Like 2

Share this post


Link to post
Share on other sites

I had some problems before that are all fixed now, somehow the following files where not transfered with FTP

/wire/core/WireMail.php

/wire/core/WireMailInterface.php

Installing and sending mail with SMTP worked fine now :)

Thanks for making this module available!

Edited by Raymond Geerts
  • Like 1

Share this post


Link to post
Share on other sites

@Raymond: Hi, this sounds that you have get the PW 2.4.0 stable. - If you have the right version, you must see at least a 2.4.1 in the backend

Version 4.3.1 isn't known. Current stable is 2.4.0 and DEV is 2.4.1

Edited by horst
  • Like 2

Share this post


Link to post
Share on other sites

Thanks horst, the problem was caused because WireMail and WireMailInterface classes where not uploaded by FTP somehow. Installing and sending works now.

I just only noticed that a form with multiple upload fields only makes the link to the first attachment available. The second attachment is always 0b and has no link. While in the FormBuilder Entries i can see both files uploaded correctly. Is this a bug in WireMail or the SwiftMailer class?

I have a form where the visitor can upload a CV and a Letter (both in doc, docx, pdf, rtf or txt format)

Share this post


Link to post
Share on other sites

@horst....Raymond is quoting what Ryan said. That was a typo (I believe, by Ryan), although he did it twice, which is baffling. See the post here

  • Like 2

Share this post


Link to post
Share on other sites

Ah, ok. (sorry @Raymond)

And also I cannot see the post in FormBuilder Forum, I believe! :)

Share this post


Link to post
Share on other sites

@horst @kongondo : i was quoting Ryan, before i edited my post. But indeed the dev branche version is 2.4.1

Share this post


Link to post
Share on other sites

Thanks teppo, Ryan, Horst, et al :D

It looks seductively like a Lego solution might exist..? Seeing your module uses Swift Mailer and these guys note Swift Mailer at the top... I wonder if there is an easy way to use their service now, thanks to this Module?

Share this post


Link to post
Share on other sites

Hey Teppo, love the module, very smooth.

I did have problems setting the name for the "to" header, ie $mail->toName = $name, or $mail->to( $addr, $name ). Neither seemed to work for me. I've replaced the top of the ___init() function as follows to make this work, may be of some use to you:

public function ___send() {

    foreach( $this->to as $k => $v )
        $toAddr[$k] = $this->toName[$k];

    // create the message
    $message = Swift_Message::newInstance()
        ->setTo($toAddr)
        ->setSubject($this->subject); 

Thanks again for the module  :)

  • Like 1

Share this post


Link to post
Share on other sites

When installing module from Module Manager on version 2.4 I get this error on install, and when I try to visit the modules page.

 Error: Class 'WireMail' not found (line 19 of /home/gelburdg/public_html/site/modules/WireMailSwiftMailer/WireMailSwiftMailer.module) 

uploading module manually seeing if it fixes it. 

Share this post


Link to post
Share on other sites

@Neeks: which ProcessWire version are you using?

WireMail was introduced in ProcessWire 2.4.1, which means that you still need current dev branch to run it. I'm assuming that this is the problem. Either that, or there's something wrong with your ProcessWire installation (less likely).

Share this post


Link to post
Share on other sites

Thanks, sorry about that I just saw "compatability 2.4" under the module page, but after reading this forum post more I realize you do mention I need the latest dev branch. Will make sure to read the whole thread before posting next time. Thanks Teppo. 

Share this post


Link to post
Share on other sites

@teppo - does WireMailSwiftMailer support attachments?

Share this post


Link to post
Share on other sites

@Macrura: sorry for the slow reply, but.. no. This is loosely related to a discussion at GitHub, here: https://github.com/ryancramerdesign/ProcessWire/issues/566. I'd like to hear what Ryan has to say about CC, BCC and attachments before going and putting together custom solution for that.

My opinion is that all of these should be implemented in the base class (WireMail) so that WireMail module authors (at the moment meaning mostly me and Horst) don't have to cook up case-by-case solutions. Even if the modules still required some customisation and couldn't use WireMail features out of the box, at least we'd have compatible implementations.

  • Like 3

Share this post


Link to post
Share on other sites

On other news, I've just updated Swift Mailer bundled with the module from 5.0.3 to 5.2.1. This version includes a security fix, so anyone using this module should update. Note that the vulnerability doesn't affect this module; it's related to Reply-To, and this module doesn't, at the moment, use that in any way, but in case that someone is using the Swift Mailer library directly from this module's directory, that could still be a problem.

Other updates added just today include minor fixes and vastly improved tools for testing mailing capabilities (including a tool for sending test messages directly from module's configuration screen).

  • Like 5

Share this post


Link to post
Share on other sites

HI Teppo

I am struggling to send mail from my new site - worked fine on my local dev server, but not on the production server.

I have installed your module to try and see if that helps. But when I try and send a test mail (any transport method) it says

 A test message was just sent to 0 recipients

Any thoughts?

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Macrura
      PrevNextTabs Module
      Github: https://github.com/outflux3/PrevNextTabs
      Processwire helper modules for adding page navigation within the editor.
      Overview
      This is a very simple module that adds Previous and Next links inline with the tabs on the page editor. Hovering over the tab shows the title of the previous or next page (using the admin's built in jqueryUI tooltips.)
      Usage
      This module is typically used during development where you or your editors need to traverse through pages for the purpose of proofing, flagging and/or commenting. Rather than returning to the page tree or lister, they can navigate with these links.
      Warnings
      If you are using PW version 2.6.1 or later, the system will prevent you from leaving the page if you have unsaved edits.
      For earlier versions, to avoid accidentally losing changes made to a page that might occur if a user accidentally clicks on one of these, make sure to have the Form Save Reminder module installed.
      http://modules.processwire.com/modules/prev-next-tabs/
    • By Gadgetto
      SnipWire - Snipcart integration for ProcessWire
      Snipcart is a powerful 3rd party, developer-first HTML/JavaScript shopping cart platform. SnipWire is the missing link between Snipcart and the content management framework ProcessWire.
      With SnipWire, you can quickly turn any ProcessWire site into a Snipcart online shop. The SnipWire plugin helps you to get your store up and running in no time. Detailed knowledge of the Snipcart system is not required.
      SnipWire is free and open source licensed under Mozilla Public License 2.0! A lot of work and effort has gone into development. It would be nice if you could donate an amount to support further development:

      Status update links (inside this thread) for SnipWire development
      2020-03-21 -- SnipWire 0.8.5 (beta) released! Improves SnipWires webhooks interface and provides some other fixes and additions 2020-03-03 -- SnipWire 0.8.4 (beta) released! Improves compatibility for Windows based Systems. 2020-03-01 -- SnipWire 0.8.3 (beta) released! The installation and uninstallation process has been heavily revised. 2020-02-08 -- SnipWire 0.8.2 (beta) released! Added a feature to change the cart and catalogue currency by GET, POST or SESSION param 2020-02-03 -- SnipWire 0.8.1 (beta) released! All custom classes moved into their own namespaces. 2020-02-01 -- SnipWire is now available via ProcessWire's module directory! 2020-01-30 -- SnipWire 0.8.0 (beta) first public release! (module just submitted to the PW modules directory) 2020-01-28 -- added Custom Order Fields feature (first SnipWire release version is near!) 2020-01-21 -- Snipcart v3 - when will the new cart system be implemented? 2020-01-19 -- integrated taxes provider finished (+ very flexible shipping taxes handling) 2020-01-14 -- new date range picker, discount editor, order notifiactions, order statuses, and more ... 2019-11-15 -- orders filter, order details, download + resend invoices, refunds 2019-10-18 -- list filters, REST API improvements, new docs platform, and more ... 2019-08-08 -- dashboard interface, currency selector, managing Orders, Customers and Products, Added a WireTabs, refinded caching behavior 2019-06-15 -- taxes provider, shop templates update, multiCURL implementation, and more ... 2019-06-02 -- FieldtypeSnipWireTaxSelector 2019-05-25 -- SnipWire will be free and open source Plugin Key Features
      Fast and simple store setup Full integration of the Snipcart dashboard into the ProcessWire backend (no need to leave the ProcessWire admin area) Browse and manage orders, customers, discounts, abandoned carts, and more Multi currency support Custom order and cart fields Process refunds and send customer notifications from within the ProcessWire backend Process Abandoned Carts + sending messages to customers from within the ProcessWire backend Complete Snipcart webhooks integration (all events are hookable via ProcessWire hooks) Integrated taxes provider (which is more flexible then Snipcart own provider) Useful Links
      SnipWire in PW modules directory SnipWire Docs (please note that the documentation is a work in progress) SnipWire @GitHub (feature requests and suggestions for improvement are welcome - I also accept pull requests) Snipcart Website  
      ---- INITIAL POST FROM 2019-05-25 ----
       
    • By horst
      Croppable Image 3
      for PW 3.0.20+
      Module Version 1.2.0
      Sponsored by http://dreikon.de/, many thanks Timo & Niko!
      You can get it in the modules directory!
      Please refer to the readme on github for instructions.
       
      - + - + - + - + - + - + - + - + - + - NEWS - 2020/03/19 - + - + - + - + - + - + - + - + - + - 
      There is a new Version in the pipe, that supports WebP too: 
       
      - + - + - + - + - + - + - + - + - + - NEWS - 2020/03/19 - + - + - + - + - + - + - + - + - + - 
       
       
      -------------------------------------------------------------------------
       
      Updating from prior versions:
       
      Updating from Croppable Image 3 with versions prior to 1.1.7, please do this as a one time step:
      In the PW Admin, go to side -> modules -> new, use "install via ClassName" and use CroppableImage3 for the Module Class Name. This will update your existing CroppableImage3 module sub directory, even if it is called a new install. After that, the module will be recogniced by the PW updater module, what makes it a lot easier on further updates.
      -------------------------------------------------------------------------
       
      For updating from the legacy Thumbnail / CropImage to CroppableImage3 read on here.
       
      -------------------------------------------------------------------------
       
    • By Robin S
      Inspired by a recent question.
      Image Crop Ratios
      Allows preset aspect ratios to be defined per image field for the ProcessWire image crop tool.
      The module adds a select dropdown to the crop tool. Choose an aspect ratio and the crop area will be fixed to that ratio.
      Screencast

      Installation
      Install the Image Crop Ratios module.
      Configuration
      Default aspect ratios for all image fields can be defined in the module config. Aspect ratios for specific image fields can be defined on the Input tab of the field settings. You can override the ratio settings in template context if needed. Insert a hyphen as the first item in the ratio settings unless you want to force a ratio to be applied to the crop tool. The hyphen represents a blank option that allows a free crop area to be drawn. Usage
      Click the "Crop" link on the details view of an image thumbnail. Click the "Crop" icon at the top of the editor window. Choose an option from the "Ratio" select dropdown.  
      https://github.com/Toutouwai/ImageCropRatios
      https://modules.processwire.com/modules/image-crop-ratios/
×
×
  • Create New...