I'm trying to configure my mailer (in this case mailgun) via config file.
My best guess was to do it in config/app.php, but didn't seem to work:
use Craft;
return [
'components' => [
'mailer' => function () {
$settings = Craft::$app->getSystemSettings()->getEmailSettings();
$settings->transportType = 'craft\mailgun\MailgunAdapter';
$settings->transportSettings = [
'domain' => 'mydomain.com',
'apiKey' => 'my-api-key',
];
return craft\helpers\MailerHelper::createMailer($settings);
},
],
];
That looks right, per the docs. You’ve installed the Mailgun plugin right?
Can't believe I missed that in the docs, but looks like i got it right…
Yep, have craftcms/mailgun installed, but doesn't appear to be working with the above config/app.php.
With that config, would you expect the settings to display in the CP Email Settings → Transport Type/Settings (they aren't).
I also verified sent some test emails and verified they _aren't_ coming through Mailgun, but the default Sendmail.
I've also tried just a Craft::dd() within the mailer function, and it doesn't seem to be getting called.
I'm trying to do the same thing, but using the Mandrill mail adapter, and am having similar issues. Dumping in config/app.phpand the code doesn't get called.
With that config, would you expect the settings to display in the CP Email Settings → Transport Type/Settings (they aren't).
So I just tested locally and it works, but the Email settings page is unaffected.
If you have Xdebug, try setting a breakpoint on line 93 of MailerHelper.php:
Otherwise just add throw $e into that catch block, so the exception can surface.
I'm debugging breakpoints in craft\helpers\MailerHelper::createMailer and still not seeing it working…
No exception is being thrown from createMailer.
For me, craft\helpers\MailerHelper::createMailer is only ever called by the adapter in the CP settings. The one config/app.php → components → mailer is never called. (I'm putting a breakpoint right at the top of createMailer , and it only breaks once, with the transport settings from the CP).
The only time it should be called is when an email is getting prepped to be sent. Are you doing something that would trigger sending an email, like sending a user an activation email?
Right, I'm testing it with the "Test" button on the settings/email screen.
Yeah try it somewhere else though. That Test button will override the saved settings with whatever was submitted in the form, so it’s not a reliable place to test your custom config.
oh, derp
Working in other contexts?
Tried this with an activation email instead of a test (was doing the same) and that works!
Slightly confusing though that the different configuration isn't reflected in the CP.
Doh, thanks for clarifying @brandonkelly.
Glad I wasn't the only one :) @janhenckens
Agree, that part confused me as well at first 🙈
OK, going forward, the Email Settings page will show this warning if app.php is defining a mailer component:

In case anyone is looking for an example configuration for this:
config/app.php:
<?php
/**
* Yii Application Config
*
* Edit this file at your own risk!
*
* The array returned by this file will get merged with
* vendor/craftcms/cms/src/config/app/main.php and [web|console].php, when
* Craft's bootstrap script is defining the configuration for the entire
* application.
*
* You can define custom modules and system components, and even override the
* built-in system components.
*/
return [
'modules' => [
'my-module' => \modules\Module::class,
],
//'bootstrap' => ['my-module'],
'*' => [
],
'dev' => [
'components' => [
'mailer' => function() {
// Get the stored email settings
$settings = Craft::$app->systemSettings->getEmailSettings();
// Override the transport adapter class
$settings->transportType = \craft\mail\transportadapters\Smtp::class;
// Override the transport adapter settings
$settings->transportSettings = [
'host' => 'smtp.mailtrap.io',
'port' => '2525',
'useAuthentication' => true,
'username' => 'USERNAME',
'password' => 'PASSWORD'
];
return craft\helpers\MailerHelper::createMailer($settings);
}
]
],
'staging' => [
'components' => [
'mailer' => function() {
// Get the stored email settings
$settings = Craft::$app->systemSettings->getEmailSettings();
// Override the transport adapter class
$settings->transportType = craft\mailgun\MailgunAdapter::class;
// Override the transport adapter settings
$settings->transportSettings = [
'domain' => 'YYYYYYYYYYYY',
'apiKey' => 'key-YYYYYYYYYYYY',
];
return craft\helpers\MailerHelper::createMailer($settings);
}
]
],
'production' => [
'components' => [
'mailer' => function() {
// Get the stored email settings
$settings = Craft::$app->systemSettings->getEmailSettings();
// Override the transport adapter class
$settings->transportType = craft\mailgun\MailgunAdapter::class;
// Override the transport adapter settings
$settings->transportSettings = [
'domain' => 'ZZZZZZZZZZZZ',
'apiKey' => 'key-ZZZZZZZZZZZZ',
];
return craft\helpers\MailerHelper::createMailer($settings);
}
]
],
];
Thanks @janhenckens, @khalwat!
Updated for Craft 3.1, thanks @Saboteur777
config/app.php:
<?php
use craft\helpers\App;
return [
'*' => [
],
'dev' => [
'components' => [
'mailer' => function() {
// Get the stored email settings
$settings = App::mailSettings();
// Override the transport adapter class
$settings->transportType = \craft\mail\transportadapters\Smtp::class;
// Override the transport adapter settings
$settings->transportSettings = [
'host' => 'localhost',
'port' => '1025',
'useAuthentication' => false,
];
$config = App::mailerConfig($settings);
return Craft::createObject($config);
}
]
],
];
Most helpful comment
In case anyone is looking for an example configuration for this:
config/app.php:
Thanks @janhenckens, @khalwat!