[wp-trac] [WordPress Trac] #29513: Move heavy lifting of wp_mail() to child class of PHPMailer
WordPress Trac
noreply at wordpress.org
Thu Sep 4 18:10:11 UTC 2014
#29513: Move heavy lifting of wp_mail() to child class of PHPMailer
---------------------------+-----------------------------
Reporter: stephenharris | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Mail | Version: trunk
Severity: normal | Keywords:
Focuses: |
---------------------------+-----------------------------
If a plug-in is sending an e-mail, the class `PHPMailer` has a lot of
useful methods (e.g. `addStringAttachment()`), but these are not available
when using `wp_mail()`, which is a requirement to work with numerous other
plug-ins owing to the hooks it triggers.
`wp_mail()` does a number of things:
1. Instantiates a `PHPMailer` instance
2. Sets default values (e.g. "from" headers, charset, content type etc. )
3. Parses the passed arguments and feeds it to the `PHPMalier` instance.
4. Executes a "pre-send" routine, (e.g. triggering hooks `wp_mail_from`,
`phpmailer_init` etc)
5. Sends the e-mail
The attached patch does a number of things:
1. Defines a `WPMailer` class ( a child of `PHPMailer`)
2. Defines a `WPMailerFactory` class which creates an instance with
appropriate default values
3. Defines 'helper' methods which do the 'heavy lifting' of (3) above
4. Overrides the preSend method of PHPMailer to execute the 'pre-send
routine' present in `wp_mail()` (i.e. (4) above)
5. Refactors `wp_mail()` to "operate" `WPMailer()` instance
The result is that developers can either use `wp_mail()` or `$wpmailer =
WPMailerFactory::getMailer()` to send e-mails, and both will behave
identically (in terms of default values, and hooks being triggered), while
maintaining backwards compatibility.
This would also effectively close tickets #28407, #28059, #23291, #15539 ,
#11376 and maybe others.
== Remarks ==
'''Why just not use `phpmailer_init`?'''
This hook is very useful, but offers no context in which `wp_mail()` is
called. As an example, suppose a plug-ins sends an e-mail with an "on-the-
fly" purchase receipt attached. At `phpmailer_init` I don't know the
purchase ID from which to generate and attach the receipt.
'''Class/method naming standards'''
I've used PHPMailer's naming standards which I understand conflicts
slightly with WordPress' naming standards. A future iteration of this
patch could well change this if that is deemed best.
'''Global $phpmailer'''
The global `$phpmailer` is redundant, as the factory creates a fresh
instance for each request. Or at least it ''would''. The ''only'' reason
the patch still uses this global, is that all the relevant unit tests pass
without any further changes. Subject to this ticket being accepted in
principle, these tests should be updated along with the patch.
'''Backwards compatability'''
Assuming `wp_mail()` hasn't been overriden by a plug-in/theme, then the is
no change in behaviour. If it has been overridden, it's clear from the
original function that the `$_GLOBAL['phpmailer']` should not be expected
to exist, nor even the required classes to be loaded. As such they can be
expected to operate independently of the changes made here, which are non-
destructive.
'''Uni tests'''
For me, the mail group unit tests pass with 1 skipped. For some reason
some tests failed (e.g. `Tests_DB::test_bail()`), but these failed even
without this patch.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/29513>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list