1

I've been trying to send Commerce emails via two different domains but I'm having very little luck getting it working fully.

In app.php I have something like this:

'mailer' => function() {
  $settings = App::mailSettings();
  
  $orderId = Craft::$app->request->getQueryParam('orderId');
  $order = Order::find()->id($orderId)->one();
  $siteHandle = $order->orderSite->handle;

  if ($siteHandle === 'siteB') {
    $transportSettings = $settings['transportSettings'];

    $settings->fromEmail = App::env('EMAIL_FROM_EMAIL_B');
    $settings->fromName  = App::env('EMAIL_FROM_NAME_B');

    $settings->transportType = $settings['transportType'];
    $settings->transportSettings = [
      'username'          => App::env('EMAIL_USERNAME_B'),
      'password'          => App::env('EMAIL_PASSWORD_B'),
      'host'              => $transportSettings['host'],
      'port'              => $transportSettings['port'],
      'useAuthentication' => $transportSettings['useAuthentication'],
    ];
  }
  
  $config = App::mailerConfig($settings);
  return Craft::createObject($config);
}

This does work but only when emails are sent via web requests. Once they're sent via the queue then obviously Craft::$app->request no longer exists.

I've not sure how to get the context of the email or the queue job at this point.

1 Answer 1

1

The answer seems to be to drop the mailer component modification completely.

There's a Yii method setTransport() which can be called via Commerce's EVENT_BEFORE_SEND_MAIL event.

Event::on(
    Emails::class,
    Emails::EVENT_BEFORE_SEND_MAIL,
    function(MailEvent $event) {
        $order = $event->order;

        $orderSite = $order->orderSite->handle;

        if ($orderSite === 'siteB') {

            $craftEmail = $event->craftEmail;
            
            $craftEmail->setFrom([ 
                App::env('EMAIL_FROM_EMAIL_B') => App::env('EMAIL_FROM_NAME_B')
            ]);

            $settings = App::mailSettings();
            $transportSettings = $settings['transportSettings'];

            $config = [
                'scheme'   => 'smtp',
                'host'     => $transportSettings['host'],
                'port'     => $transportSettings['port'],
                'username' => App::env('EMAIL_USERNAME_B'),
                'password' => App::env('EMAIL_PASSWORD_B'),
            ];

            Craft::$app->mailer->setTransport($config);
        }
    }
);

Possibly necessary to set the transport back to default by using the EVENT_AFTER_SEND_MAIL event too.

1
  • You should be able to access the Mailer instance that created the email by doing $event->craftEmail->mailer, which means you should be able to do $event->craftEmail->mailer->setTransport(..., which might mean you could change the mailer config temporarily for just this email and not have to bother with resetting the config?
    – Jalen Davenport
    Commented May 17 at 19:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.