Zen Cart Logo
Forums / Zen Cart Code Suggestions / Allow observer to override sending additional order confirmation email

Allow observer to override sending additional order confirmation email

Views: 76

Results 1 to 10 of 10
17 Jul 2021, 17:24
#1
dave224 avatar

dave224

Zen Follower

Join Date:
Jun 2012
Posts:
481
Plugin Contributions:
0

Allow observer to override sending additional order confirmation email

I need to not send additional order confirmation emails to store personnel but only for orders generated by a point-of-sale addon. In includes/classes/order.php, where the customer order confirmation email is generated and sent, the following code does exactly what I need.

    // Send customer confirmation email unless observer overrides it.
    $send_customer_email = true;
    $this->notify('NOTIFY_ORDER_INVOICE_CONTENT_READY_TO_SEND', array('zf_insert_id' => $zf_insert_id, 'text_email' => $email_order, 'html_email' => $html_msg), $email_order, $html_msg, $send_customer_email);
    if ($send_customer_email === true) {
        zen_mail($this->customer['firstname'] . ' ' . $this->customer['lastname'], $this->customer['email_address'], EMAIL_TEXT_SUBJECT . EMAIL_ORDER_NUMBER_SUBJECT . $zf_insert_id, $email_order, STORE_NAME, EMAIL_FROM, $html_msg, 'checkout', $this->attachArray);
    }

For orders from the POS code, I set $send_customer_email to false in the observer to that notifier, and no email is sent to the customer.

But there is no similar code later where additional extra order confirmation emails are generated. In the interest of not modifying core code, can similar code be inserted before sending the additional order confirmation emails in a future zen cart version? This solution may be the most flexible and general. Or some other solution implemented?

One other solution is a simple mod to order.php in the check on SEND_EXTRA_ORDER_EMAILS_TO to also check $send_customer_email, which would work for my case.

Another more general, but complex solution could involve the notifier in the extra order confirmation code (NOTIFY_ORDER_INVOICE_CONTENT_FOR_ADDITIONAL_EMAILS) where an observer could potentially manipulate $email_order and $html_msg so that function zen_mail does not send the email. But $extra_info['TEXT'] is appended to $email_order in the call to zen_mail and there is no way to blank out $extra_info['TEXT'] since it is not passed to the observer, is not a global variable, and is not a class variable. If $extra_info were passed or was a class variable, this solution could be used. Or $extra_info['TEXT'] could be appended to $email_order before the notifier. Then $email_order could be set to '' and $html_msg['EMAIL_MESSAGE_HTML'] set to '' so zen_mail won't send the email.

The only way to do what I want with the current code is to have nothing set in SEND_EXTRA_ORDER_EMAILS_TO and redo the code for the additional emails within an observer of another notifier (NOTIFY_ORDER_AFTER_SEND_ORDER_EMAIL), a not very efficient method.

There are several simple solutions to my problem for future zen cart versions, some of which I have outlined above. There are probably other simple solutions too, perhaps more elegant. I hope something will be implemented.

Dave
zc157c, php 7.3.x

18 Jul 2021, 17:53
#2
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: Allow observer to override sending additional order confirmation email

So, I can't seem to figure out what is used to determine whether the email should go to the "extra" group or not, but if I may make a few observations about the code and add to some other observer related software has been added to the ZC plugins area.

It sounds like what you want to do is to allow emails to go through for particular customers to the customer and for some of those emails to go through for "admin". You have figured out how to prevent an email from going to a customer and (it appears) that preventing the email from going to the customer is successful and at the same time this prevents the email from going to the admin which is also desired.

And all of this is leading to a desire to be able for some instances (POS ordering) to send the customer the email but not the admin... (Note to others, a further assumption is that while the store is being used/accessed as a POS that the store is also live accepting orders so not helpful to change email addresses and/or settings related to enabling/disabling the additional emails overall for the store).

So, there is one or more notifiers in includes/functions/functions_email.php within the zen_mail function that can help with your situation. The way to pull all together is for your observer class to "communicate" with itself and take the action desired...

I see that this could be done by listening to a few notifiers and having/receiving a signal of when to alter action with the admin/duplicate email from your other/trigger source.

Basically that if the alternate email is not to be sent then the notifier in zen_mail (NOTIFY_EMAIL_DETERMINING_EMAIL_FORMAT) cause $customers_email_format to be equal to 'NONE'. This will prevent that email to not be sent and also as of right now to prevent any further emails within the reviewed email addresses from being sent.

So it would be something like:
Review the condition of the email being sent from the order class. If to be sent to customer, but not to admin, then call zen_email to send the message. Once in zen_email, listen to a notifier that is before the one I mentioned or even the one mentioned. If not to send the admin, allow the message to go through. Listen to either the end of the zen_mail function (at which point to indicate internally that done with sending the real customer emails, or listen until some other trigger point that prevents sending the email. In either of those, indicate that done sending to the customer(s).
Then while listening to the above mentioned notifier, if are done sending to customers and not to send to admin, change the setting so that emails are not sent. As part of changing that setting, remove the tracers for whether the email should be sent to the admin and that done sending to the customer(s). This way, the next action that is being listened to can send email(s).

At any rate, there is no need to modify the core code to determine if the email needs to be sent or to prevent the overall sending of the email.

As far as the discussion of altering $email_info['TEXT'] and similar, while the code will exit if there is nothing to send, it is not the only way in which to cause that to happen and as described, yes it would take effort to reproduce the code that already exists (and can be used to prevent sending the email).

19 Jul 2021, 19:30
#3
dave224 avatar

dave224

Zen Follower

Join Date:
Jun 2012
Posts:
481
Plugin Contributions:
0

Re: Allow observer to override sending additional order confirmation email

So, I can't seem to figure out what is used to determine whether the email should go to the "extra" group or not, but if I may make a few observations about the code and add to some other observer related software has been added to the ZC plugins area. What I need is for the email to go to the extra group only if an email is sent to the customer.

It sounds like what you want to do is to allow emails to go through for particular customers to the customer and for some of those emails to go through for "admin". You have figured out how to prevent an email from going to a customer and (it appears) that preventing the email from going to the customer is successful and at the same time this prevents the email from going to the admin which is also desired. Any emails going to a customer should also go to the extra group. I have figured out how to prevent emails going to POS customers, but not for preventing those emails to go to the extra group without a core modification (adding a check on $send_customer_email to the check on whether SEND_EXTRA_ORDER_EMAILS_TO is !'').

And all of this is leading to a desire to be able for some instances (POS ordering) to send the customer the email but not the admin... (Note to others, a further assumption is that while the store is being used/accessed as a POS that the store is also live accepting orders so not helpful to change email addresses and/or settings related to enabling/disabling the additional emails overall for the store). No, I want to prevent the email from going to both customers and the extra group for POS orders, but allow the email to go to both the customer and to the extra group for all other normal store orders. You are correct that normal store operations are active when POS operations are ongoing (and when POS is not operating).

I had forgotten about an approach where an observer listens to multiple notifiers. Thank you for the reminder and the notifier hint in zen_mail! It's always interesting to me to get your perspective on things. Thanks again.

Dave

19 Jul 2021, 19:49
#4
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: Allow observer to override sending additional order confirmation email

Now, the question is, do you want to go through the effort of self developing a solution, or to possibly be fed a potential solution? I had worked out something, but hate to take away someone's "fun" if they are determined.

19 Jul 2021, 19:56
#5
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: Allow observer to override sending additional order confirmation email

Now, the question is, do you want to go through the effort of self developing a solution, or to possibly be fed a potential solution? I had worked out something, but hate to take away someone's "fun" if they are determined.

19 Jul 2021, 20:27
#6
dave224 avatar

dave224

Zen Follower

Join Date:
Jun 2012
Posts:
481
Plugin Contributions:
0

Re: Allow observer to override sending additional order confirmation email

Lay it on me mc...!
Dave

19 Jul 2021, 20:31
#7
dave224 avatar

dave224

Zen Follower

Join Date:
Jun 2012
Posts:
481
Plugin Contributions:
0

Re: Allow observer to override sending additional order confirmation email

Does it involve saving $send_customer_email in the observer that sets it false for POS orders and tests it in an observer to NOTIFY_EMAIL_DETERMINING_EMAIL_FORMAT? I don't want to spoil your fun too!
Dave

19 Jul 2021, 20:37
#8
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: Allow observer to override sending additional order confirmation email

So, to put the above discussion possibly in code format...

includes/classes/observers/auto.email_admin_additional_block.php

<?php

class zcObserverEmailAdminAdditionalBlock extends base
{
    function __construct()
    {
        $observeThis = array();
        $observeThis[] = 'NOTIFY_ORDER_INVOICE_CONTENT_READY_TO_SEND'; // Determine if customer should receive the email
        $observeThis[] = 'NOTIFY_EMAIL_DETERMINING_EMAIL_FORMAT'; // Notifier where it is possible to cancel the email being sent.
        $observeThis[] = 'NOTIFY_ORDER_INVOICE_CONTENT_FOR_ADDITIONAL_EMAILS'; // Track that at the point in code generating the additional email
        $observeThis[] = 'NOTIFY_ORDER_AFTER_SEND_ORDER_EMAIL'; // Notifier after the emails have been sent for this instance

        $this->attach($this, $observeThis);
    }

//    $this->notify('NOTIFY_ORDER_INVOICE_CONTENT_READY_TO_SEND', array('zf_insert_id' => $zf_insert_id, 'text_email' => $email_order, 'html_email' => $html_msg), $email_order, $html_msg, $send_customer_email);
    // Determine if customer should receive the email
    function notify_order_invoice_content_ready_to_send(&$callingClass, $notifier, $readData, &$email_order, &$html_msg, &$send_customer_email) {
        if ($this->dontSendAdm()) {
            $this->noAdminEmail = true;
        }
        if ($this->dontSendCust()) {
            $send_customer_email = false;
        }
    }

    function dontSendAdm() {
        /* This function is to return whether the admin should receive an email or not.
        */
        return false; // <- Send the admin an email (didn't want to disable such email for all cases while working on the logic).
    }

    function dontSendCust() {
        /* This function is to return whether the customer should receive an email or not. Ideally this is possible to determine in any of these function observers without
               "extra" processing/data collection.
        */
        return false; // <- Send the customer an email. (At least until the logic is in place to allow this to prevent customer receipt)
    }

//      $this->notify('NOTIFY_ORDER_INVOICE_CONTENT_FOR_ADDITIONAL_EMAILS', $zf_insert_id, $email_order, $html_msg);
    // Track that at the point in code generating the additional email
    function notify_order_invoice_content_for_additional_emails(&$callingClass, $notifier, $zf_insert_id, &$email_order, &$html_msg) {
        $this->additional_emails = true;
    }

//      $zco_notifier->notify('NOTIFY_EMAIL_DETERMINING_EMAIL_FORMAT', $to_email_address, $customers_email_format, $module);
    // Notifier where it is possible to cancel the email being sent.
    function notify_email_determining_email_format(&$callingClass, $notifier, $to_email_address, &$customers_email_format, &$module) {
        if (!empty($this->additional_emails) && !empty($this->noAdminEmail)) {
            $customers_email_format = 'NONE';
        }
    }

//    $this->notify('NOTIFY_ORDER_AFTER_SEND_ORDER_EMAIL', $zf_insert_id, $email_order, $extra_info, $html_msg);
    // Notifier after the emails have been sent for this instance
    function notify_order_after_send_order_email(&$callingClass, $notifier, $zv_insert_id, &$email_order, &$extra_info, &$html_msg) {
        if (isset($this->additional_emails)) {
            unset($this->additional_emails);
        }

        if (isset($this->noAdminEmail)) {
            unset($this->noAdminEmail);
        }
    }
}

Obviously some "work" has to be done regarding the two methods in the function about sending the admin or customer emails. That test could just be in the original line; however, I was trying to go for a more "generic" solution where the logic to determine if the email should be sent would be specific to the store. That in itself could be a notifier possibly, but... if so, be sure that the sequence of observers supports actually observing that notifier.

19 Jul 2021, 21:05
#9
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: Allow observer to override sending additional order confirmation email

Dave224:

Does it involve saving $send_customer_email in the observer that sets it false for POS orders and tests it in an observer to NOTIFY_EMAIL_DETERMINING_EMAIL_FORMAT? I don't want to spoil your fun too!
Dave

In a way I guess it does that. :)

I had written it before getting the previous explanation, so the area associated with determining when to allow/disable sending the email(s) doesn't fully incorporate the described logic. It also didn't include the "flag" that was being used to determine if the "purchase" was from POS or otherwise, but I would expect that is something "easily" incorporated from whatever was already being used.

21 Jul 2021, 10:42
#10
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: Allow observer to override sending additional order confirmation email

Curious. How much modification was necessary for this to work and/or how well did it work for the proposed operation?