Send email from inside Commerce via basic mail.modPHPMailer service

Hi,
I’m using custom registered Commerce module(class extends BaseModule) for various needs.

I need to register user and send registration email. I’m working here:

 public function updateAddress($event)

Yes, I can register new MODX user via pure MODX API (Adapter is useful here), but for some reason I can’t send email and stuck here((

I can get service next way:

$this->adapter->getService('mail', 'mail.modPHPMailer');

but further (assigning fields, sending) … nothing works. Let me remind in “pure” MODX it is done like this.

$modx->getService('mail', 'mail.modPHPMailer');
$modx->mail->set(modMail::MAIL_BODY,$message);
$modx->mail->set(modMail::MAIL_FROM,'me@example.org');
$modx->mail->set(modMail::MAIL_FROM_NAME,'Johnny Tester');
$modx->mail->set(modMail::MAIL_SUBJECT,'Check out my new email template!');
$modx->mail->address('to','user@example.com');
$modx->mail->address('reply-to','me@xexample.org');
$modx->mail->setHTML(true);
if (!$modx->mail->send()) {
    $modx->log(modX::LOG_LEVEL_ERROR,'An error occurred while trying to send the email: '.$modx->mail->mailer->ErrorInfo);
}
$modx->mail->reset();

Please advise.

$mail = $this->adapter->getService('mail', 'mail.modPHPMailer');
$mail->set(...);
$mail->address(...);
Etc

Alternatively if an email is order related, create it as an order message instead of sending it directly.

1 Like

Thanks a lot!

it should look like this, but after any SET call script is interrupted, there are no errors in the log. F.E.

$mail = $this->adapter->getService('mail', 'mail.modPHPMailer'); // THIS IS OK
$mail->set(modMail::MAIL_FROM,'my@email.com'); // INTERRUPTION`

unfortunately, this problem is still relevant, why is there a gag here? I can’t understand((, maybe someone has a fresh look from a different angle. Many thanks!

I dont know, that looks fine to me. Did you check the php/apache log?

Hi there,
interesting topic.

So, first, let me confirm the above service call works for my module (class extends BaseModule) as well

        $mail = $this->adapter->getService('mail', 'mail.modPHPMailer');
        if (!$mail instanceof modMail) {
            $this->adapter->log(1, '[Commerce.comOrderEmailMessage] Could not send email: unable to load modMail');
            return false;
        }
	$mail->reset();
	$mail->set(modMail::MAIL_BODY, 'MODX COMMERCE IS THE BEST');
        $mail->set(modMail::MAIL_FROM, $this->commerce->getOption('emailsender'));
        $mail->set(modMail::MAIL_FROM_NAME, $this->commerce->getOption('site_name'));
        ...

Second, I am calling the above code from function which is getting executed on Event registered as follows:

public function initialize(EventDispatcher $dispatcher)
    {
         $dispatcher->addListener(\Commerce::EVENT_SEND_MAIL,[$this,'onBeforeOrderEmailSent']);
         ....

and here is that function:

public function onBeforeOrderEmailSent(\modmore\Commerce\Events\Mail $event){
   //phpmailer call
   //email $body needs to be order details and user name
   $mail->set(modMail::MAIL_BODY, $body);
   ....
}

I have 2 concerns:

  1. maybe I am using wrong event registration or wrong implementation since that event is called 2 times per 1 order.
  2. what is the best method of loading order data such as items and user details, please?
    I can do $order = $event->getOrder(); for items but not sure if it’s best method…

Anyone please advise, thank you

1 Like

\Commerce::EVENT_SEND_MAIL is triggered once for every email sent by Commerce, and is meant to change the email that is being sent, like adding extra headers or an attachment.

The default statuses setup sends 2 emails per order so yes you’ll see that twice.

You probably want to use \Commerce::EVENT_STATE_CART_TO_PROCESSING instead to run when an order is placed and paid.

$order = $event->getOrder() is correct.

$order = $event->getOrder(); is the right method to use. From there you can get to items with $order->getItems() and the user ID will be in $order->get('user') (which can be 0 for anonymous).

1 Like

Thanks very much indeed Mark.