? ? Pending

User tests: Successful: Unsuccessful:

avatar mbabker
mbabker
14 Jan 2018

Summary of Changes

Right now Joomla's mail system is essentially a subclass of the main PHPMailer class with some interesting design quirks, including:

  • Singleton object storage
  • Function signatures deviating from the parent source

For the first issue, this can be problematic as any PHP object representing an email message really should be a one-and-done object, not persisted in storage and reusable. The second issue is just bad API design and at this point pretty difficult to fix.

Instead of trying to redesign Joomla\CMS\Mail\Mail (the subclass to PHPMailer's base class), I think we're better off introducing a service layer in front of PHPMailer so that we don't have an API that is explicitly dependent on PHPMailer (core could move to Swiftmailer or any other PHP mailing library if desired/needed) and addresses the design issues in the existing class.

This is accomplished by introducing three new interfaces to our API with implementations defaulting to PHPMailer.

Joomla\CMS\Mail\MailerFactoryInterface

This is the main entry point into the redesigned mail API. Through this service factory you would create a mailer object to interface with the chosen mail package/transport.

Joomla\CMS\Mail\MailerInterface

This object is a "manager" of sorts for interacting with the underlying package/transport and is responsible for creating new messages. In the case of our default PHPMailer implementation, it exposes the callback function to be used by default for debug statements as well.

Joomla\CMS\Mail\MailMessageInterface

This object represents a single email message and is the object you will be working with primarily, this is where you'd do things like set the message body or the address list.

Testing Instructions

Essentially, the new API boils down to this:

use Joomla\CMS\Factory;

$mailFactory = Factory::getContainer()->get('mailer.factory');

$mailer = $mailFactory->createMailer();

$message = $mailer->createMessage();
$message->setBody('My text');
$message->setSubject('Testing message');
$message->addRecipient('you@example.com', 'You the Reader');
$message->send();

For more advanced cases where you might want/need to work directly with the underlying transport, the MailMessageInterface interface has a getMailer method which gives access to that object, which in the case of this default implementation is the PHPMailer class instance which the message is based on.

TODO

  • Finish implementation
  • Discuss deprecations

Documentation Changes Required

TBD

avatar mbabker mbabker - open - 14 Jan 2018
avatar mbabker mbabker - change - 14 Jan 2018
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 14 Jan 2018
Category Libraries
avatar brianteeman
brianteeman - comment - 24 Jan 2018

Seems like a good step forward - especially the ability to switch the library if we want or need to

avatar mbabker mbabker - change - 27 Jan 2018
Labels Added: ? ?
avatar photodude
photodude - comment - 2 Feb 2018

More flexibility and less hard dependencies is usually a good thing.

avatar mbabker
mbabker - comment - 17 Apr 2018

I'm trying to bounce this off of SwiftMailer and PHPMailer to create base functionality and ensure most sane configurable things are exposed. The one bit I'm missing is attachment support. I'll come to that soon.

Outstanding items to discuss/address:

  • Right now messages are write only, to read means accessing the underlying library. Do we want read access in the interface?
  • Should we expose something to handle configuring messages as HTML versus plain text, or leave that to accessing the underlying library to configure? (This gets a little trickier as some libraries support setting a different body for text and HTML)
  • Mail is one part of the API that is not hookable. SwiftMailer does have its own event system, PHPMailer doesn't. Do we want our interface to be dispatcher aware and dispatch events to allow plugins to customize messages, and if so what types of events (pre/post send minimum most likely). A pro of events is it becomes a lot easier to hook core to style HTML formatted messages.
avatar brianteeman
brianteeman - comment - 17 Apr 2018
  1. Can you explain what read access would be? I dont see anything in either libraries for this.
    If you mean the ability to have the web site access a mail inbox and act upon the contents of an email - eg email2content then that would be a nice to have but thats all

  2. An option to choose either plain text or html would be good. Not sure I see the need to have anything more than that.

  3. yes

avatar mbabker
mbabker - comment - 17 Apr 2018

The interface only has set methods right now (write access). The interface doesn't expose get methods (read access). So you couldn't in code call getSubject to check the message's subject.

avatar brianteeman
brianteeman - comment - 17 Apr 2018

I cant see the usecase for that then?

avatar mbabker
mbabker - comment - 17 Apr 2018

So especially if there is event support, something manipulating a message before it is sent right now can't rely on our interface to read data about the message (subject, recipients, etc.). To do that you have to call the getMailer method to access the underlying library, and use that library's API to read data (losing some of the benefit of having an abstraction layer to begin with).

avatar wilsonge
wilsonge - comment - 2 May 2018

@Hackwar do you have any strong feelings on the event dispatcher stuff based on the work you've talked about with having email templates?

avatar wilsonge
wilsonge - comment - 2 May 2018
  1. No
  2. Yes
  3. Maybe? This might be a case where the base interface doesn't have to be DispatcherAware but the concrete implementation should
avatar photodude
photodude - comment - 3 May 2018

If I ever get around to it, I'll have to look into considering genkgo/mail
Seems the basic functionality here should make it easy (but I haven't looked in depth).

avatar mbabker
mbabker - comment - 6 Aug 2018

I don't have the time or energy to push through with what is essentially change for the sake of change. If I can think of ways to improve Joomla\CMS\Mail\Mail within the confines of that class' design I'll submit something. Otherwise, feel free to fork and iterate if so interested.

avatar mbabker mbabker - change - 6 Aug 2018
Status Pending Closed
Closed_Date 0000-00-00 00:00:00 2018-08-06 23:52:17
Closed_By mbabker
avatar mbabker mbabker - close - 6 Aug 2018

Add a Comment

Login with GitHub to post a comment