dev/core#2141 - Add hook_civicrm_alterMailStore
Overview
--------
The CiviCRM "MailStore" layer is used for importing email messages from
various sources (IMAP, POP3, Maildir, etc). There is a built-in list with a
handful of drivers (`CRM_Mailing_MailStore_Imap`, etc).
This patch adds a hook for manipulating those drivers.
Before
------
It's not possible for an extension to add a driver, modify a driver, etc.
After
-----
It is now possible to add/modify/replace drivers. Here are two examples.
(1) To supplement the IMAP authentication with a dynamic token for XOAuth2:
```php
function hook_civicrm_alterMailStore(&$mailSettings) {
if (...$mailSettings requires oauth...) {
$mailSettings['auth'] = 'XOAuth2';
$mailSettings['password'] = $myOauthSystem->getToken(...);
}
}
```
(2) To add a new protocol `FIZZBUZZ`, you would:
1. Register a value in the OptionGroup `mail_protocol`.
2. Create a driver class (eg `CRM_Mailing_MailStore_FizzBuzz` extends `CRM_Mailing_MailStore`)
3. Use the hook to activate the class:
```php
function hook_civicrm_alterMailStore(&$mailSettings) {
if ($mailSettings['protocol'] === 'FIZZBUZZ') {
$mailSettings['factory'] = function ($mailSettings) {
return new CRM_Mailing_MailStore_FizzBuzz(...);
};
}
}
```
Technical Details
-----------------
This adds a unit-test with examples of basic/non-hook behavior and hooked behavior.
In reading the diff for `getStore()`, note that it previously had a long
'switch()' to handle instantiation. I tried to make the change in a way that
you could see some continuity - e.g. it's still the same basic `switch()`.
The change is to basically wrap the bits inside a function:
* Before: `case 'FOO': return new Foo(...)`
* After: `case 'FOO': return ['factory' => function(...) { return new Foo(...); }]`