(REF) Move CIVICRM_MAIL_LOG logic from patch-files to wrapper-class
authorTim Otten <totten@civicrm.org>
Fri, 7 Feb 2020 23:15:14 +0000 (15:15 -0800)
committerTim Otten <totten@civicrm.org>
Fri, 7 Feb 2020 23:15:14 +0000 (15:15 -0800)
commitb2423c39e732d17d15127f959f4bb756f1551797
treeffee1992b0f07f6818048aaf86fc6e386647052a
parent7632d43742dfcd528736528da8fd3387afa3f57e
(REF) Move CIVICRM_MAIL_LOG logic from patch-files to wrapper-class

Overview
--------

This aims to improve maintainablity and deployment workflows by reduing the
scope of the needed files.

It is an alternative approach for #16481.

Before
------

`civicrm-core` included patch files for `pear/mail`.  These files modified
the behavior of `Mail_sendmail`, `Mail_smtp`, and `Mail_mail` to ensure that
the `send()` function would abide by the `CIVICRM_MAIL_LOG` constant.

After
-----

`civicrm-core` includes a wrapper class `LoggingMailer`.  It takes an
instance of `Mail_sendmail`, `Mail_smtp`, or `Mail_mail` and mixes-in the
`CIVICRM_MAIL_LOG` logic.

Technical Details
-----------------

There is a `hook_civicrm_alterMailer`, for which consumers could potentially
see a change in behavior (because the concrete-class of `$mailer` may
change and support different properties). Mitigating factors:

* There is only one public method in the `Mail` contract: `send()`.
* The only example of `alterMailer` in the documentation suggests
  that you wholly replace the object with your own implementation.
  This was the original purpose. If you use it this way, then it doesn't
  matter what's happening inside the old object.
  https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_alterMailer/
* In public `universe`, there is only one extension (Cividesk's Sparkpost)
  which uses this hook. And it does swap in that expected way.
* Just in case... the `LoggingMailer` passes-through all calls to read/write properties.
  You can see this in action in a specific configuration, e.g.
  ```
  ## Before patch
  $ cv ev '$m=Civi::service("pear_mail"); return [get_class($m), $m->host];'
  [
      "Mail_smtp",
      "127.0.0.1"
  ]

  ## After patch
  $ cv ev '$m=Civi::service("pear_mail"); return [get_class($m), $m->host];'
  [
      "CRM_Utils_Mail_LoggingMailer",
      "127.0.0.1"
  ]
  ```
CRM/Utils/Mail.php
CRM/Utils/Mail/LoggingMailer.php [new file with mode: 0644]
tools/scripts/composer/patches/pear-mail.patch.txt