User tests: Successful: Unsuccessful:
Right now Joomla's mail system is essentially a subclass of the main PHPMailer class with some interesting design quirks, including:
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.
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.
TBD
Status | New | ⇒ | Pending |
Category | ⇒ | Libraries |
Labels |
Added:
?
?
|
More flexibility and less hard dependencies is usually a good thing.
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:
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
An option to choose either plain text or html would be good. Not sure I see the need to have anything more than that.
yes
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.
I cant see the usecase for that then?
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).
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).
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.
Status | Pending | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2018-08-06 23:52:17 |
Closed_By | ⇒ | mbabker |
Seems like a good step forward - especially the ability to switch the library if we want or need to