I am trying to add a function that will log any email that is sent through order status changes.
Is there a hook I can use that is triggered right before an order notification email is sent?
Updated
All the available hooks responsible for triggering email notifications are located in WC_Emails init_transactional_emails() method and are action hooks:
woocommerce_low_stock,
woocommerce_no_stock,
woocommerce_product_on_backorder,
woocommerce_order_status_pending_to_processing,
woocommerce_order_status_pending_to_completed,
woocommerce_order_status_processing_to_cancelled,
woocommerce_order_status_pending_to_failed,
woocommerce_order_status_pending_to_on-hold,
woocommerce_order_status_failed_to_processing,
woocommerce_order_status_failed_to_completed,
woocommerce_order_status_failed_to_on-hold,
woocommerce_order_status_on-hold_to_processing,
woocommerce_order_status_on-hold_to_cancelled,
woocommerce_order_status_on-hold_to_failed,
woocommerce_order_status_completed,
woocommerce_order_fully_refunded,
woocommerce_order_partially_refunded,
woocommerce_new_customer_note,
woocommerce_created_customer.
Each of those action hooks can queue or send transactional emails as you will see in the source code on line 95 or on line 99.
Last thing for the new order notification, which is a bit appart, you will use one of those:
woocommerce_order_status_pending_to_processing_notification,
woocommerce_order_status_pending_to_completed_notification,
woocommerce_order_status_pending_to_on-hold_notification,
woocommerce_order_status_failed_to_processing_notification,
woocommerce_order_status_failed_to_completed_notification,
woocommerce_order_status_failed_to_on-hold_notification,
as documented in this WC_Email_New_Order code source.
Or you can detect status changes using one of the 3 hooks located in status_transition() WC_Order method:
woocommerce_order_status_changed
woocommerce_order_status_{$status_transition[from]}_to_{$status_transition[to]}
woocommerce_order_status_{$status_transition[to]}
The status_transition() is included in set_status() WC_Order method (and so also update_status() method too which call set_status()).
Related
In Woocommerce, there is already a built-in way to add recipients to the "New Order" , "Failed", and "Cancelled" emails, but for some reason, the "Customer invoice / Order details" don't allow any recipient other than the customer.
There is a simple plugin that allows for that, but it is very limited in features.
Any guidance for how to add recipients to this email?
I plan to use a Code Snippet to call the hook/filter/action and then tell it explicitly which email addresses to use. I intend to write the script so that whatever user initiates the action, will be CC'ed on that email. Presumably the same function that can do the first part of my question can help me to check current user and will grab their email address.
Any help is appreciated
I don't know what buil-in functionality are you talking about. But you can use the below filter to add recipients to the invoice email. You don't need any plugin, just use this below code snippet in your active theme/child theme functions.php
add_filter("woocommerce_email_recipient_customer_invoice", "add_recipient_to_email", 10, 2);
function add_recipient_to_email( $recipients, $object ){
$new_email = "newemail#domain.com"; //New email Id
$recipients = $recipients.','.$new_email;
return $recipients;
}
I have added a custom shipping option which works great, however duplicate emails are sent - my custom shipping new order email and the standard admin new order email.
In WooCommerce > Settings > Email I have added a new option for my custom shipping and added recipients and so on. What I think I need to do now is put a condition in to the Admin New Order section, something along the lines of..
if(shipping method == 'Custom Shipping')
return; // this can just bail out as a custom shipping email is being sent
I think this will stop the standard new order email being sent if the order uses Custom Shipping.
Can anyone give me guidance on how I can implement this? Do I put code in to the admin-new-order.php file with this if statement? Thank you
You could remove the standard mail actions: https://docs.woocommerce.com/document/unhookremove-woocommerce-emails/
And then intercept the order_status_changed hook to trigger your mail depending on conditions (like the shipping method): https://docs.woocommerce.com/wc-apidocs/class-WC_Order.html
function your_function($id)
{
$order = wc_get_order($id);
if (!empty($order) && $order->get_shipping_method() === 'Custom Shipping') {
do_action('woocommerce_before_resend_order_emails', $order, 'email_name');
// prepare your email
do_action('woocommerce_after_resend_order_email', $order, 'email_name');
}
}
add_action('woocommerce_order_status_changed', 'your_function');
I am trying to add a Logic Hook for Emails synced from IMAP Mail server.
In the end i want trigger a hook when a new mail gets synced and check the senders mail if its saved in one of the accounts.
The problem is that the Synced Mails dont get saved (at least not in InboundMail or Emails module) so the after/before_save does not trigger.
Here is my hook from logic_hooks.php:
$hook_array['after_save'][] = Array(1, 'Create Lead', 'custom/modules/InboundEmail/LeadLogicHook.php', 'LeadLogicHook', 'handleLead');
It does not work in InboundEmail and Email Module.
And the LeadLogicHook:
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
class LeadLogicHook
{
function handleLead($bean, $event, $arguments)
{
_ppl("Test");
}
}
Is this even possible with logic hooks?
EDIT: Added some Code
No need for logic hook or any other custom code. Sugar/SuiteCRM use a scheduler job to fetch email from IMAP server. You can check scheduler job function (function::pollMonitoredInboxes) which fetch emails. That contain code which is used for email fetching. track back code and you will find everything you want.
What version of sugar are you using?
You can, for example, generate an after_save hook in the E-mail module instead of inboundEmail
Would be like this:
$hook_array ['after_save'] [] = Array (1,'Create Lead','custom/modules/Emails/LeadLogicHook.php','LeadLogicHook','handleLead');
Do this and see if the email fires!
Another possibility would be to use the after_relationship_add, because usually, the email is associated with some lead, account, or contact. try to create a hook in the module that your email is associating with and generate the operation from there
one last possibility (I do not recommend this) is to create a trigger in your database for when the data enters the table, perform the check and take some action
I think it's possible, if after/before_save not triggering then try some similar logic hooks. The following are some logic hooks that I think could help.
before_retrieve
after_retrieve
before_restore
after_restore
server_roundtrip
after_session_start
after_entry_point
Comment if you want more details, like how to use logic hooks e.t.c.
In previous versions of Woocommerce, an email notification was sent automatically when an order was changed from pending status to cancelled status (In my case, this happens after an allotted time set in the inventory section of the admin).
In WooCommerce 3.0.8 they have removed this automation and labelled as a fix:
https://github.com/woocommerce/woocommerce/blob/master/CHANGELOG.txt
And the pull request is here:
https://github.com/woocommerce/woocommerce/pull/15170/files
I'm looking to restore this functionality, but obviously copy/pasting this line back in to the Woocommerce core files isn't a good idea as it will get overwritten when the platform updates.
I know the best method would to be to create a function and hook into the cancelled order action via functions.php but after having a look I'm a bit lost about how to do this. Here is the line which was replaced:
add_action( 'woocommerce_order_status_pending_to_cancelled_notification', array( $this, 'trigger' ), 10, 2 );
How can I restore this old automated functionality?
The good new: Using woocommerce_order_status_pending_to_cancelled action hook with a custom function hook in it, solve your problem definitively:
add_action('woocommerce_order_status_pending_to_cancelled', 'cancelled_send_an_email_notification', 10, 2 );
function cancelled_send_an_email_notification( $order_id, $order ){
// Getting all WC_emails objects
$email_notifications = WC()->mailer()->get_emails();
// Sending the email
$email_notifications['WC_Email_Cancelled_Order']->trigger( $order_id );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and perfectly works in WooCommerce 3+ (still work on version 4.8+)
I am trying to write a module that syncs my newsletter subscribers in Magento with a external database. I need to be able to update the subscription status in Magento programmatically but I am having diffuculty getting the "setStatus" method in Magento to work. It does not throw any errors but the code does not seem to have any effect. Below is the code where I call the method:
$collection = Mage::getResourceModel('newsletter/subscriber_collection')->showStoreInfo()->showCustomerInfo();
foreach ($collection as $cust) {
$cust->setStatus(1);
}
In theory, this should set the status of all of my subscribers to "subscribed". I could optionally change the argument sent to "setStatus" to any of the below ints for a different status.
1: Subscribed
2: Status Not Active
3: Unsubscribed
How to best change the subscriber status or get this code working?
Here an import script:
<?php
require_once("./app/Mage.php");
Mage::app();
$subscribers = array('email1#server1.com', 'email2#server2.com');
foreach ($subscribers as $email) {
# create new subscriber without send an confirmation email
Mage::getModel('newsletter/subscriber')->setImportMode(true)->subscribe($email);
# get just generated subscriber
$subscriber = Mage::getModel('newsletter/subscriber')->loadByEmail($email);
# change status to "subscribed" and save
$subscriber->setStatus(Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED);
$subscriber->save();
}
?>
It seems that newsletter subscribers are also stored elsewhere. What you are setting is just a check in the customer base for some other use.
You need to do the following for each customer as well.
Mage::getModel('newsletter/subscriber')->subscribe($email);
See this link for a complete reference.
Thanks to the link #Ozair shared I was able to figure out what I needed to do.
I was successfully setting the status of the subscriber in the Magento subscriber object but I was not saving the object. I needed to call Magento's save method so it would call the ORM and write it to the database. All I need to do was add
$cust->save();
in the for loop. Below is the whole code snippet.
$collection = Mage::getResourceModel('newsletter/subscriber_collection')->showStoreInfo()->showCustomerInfo();
foreach ($collection as $cust) {
$cust->setStatus(1);
$cust->save();
}
I Hope this helps someone in the future. I needed it for a Constant Contact - Magento Synchronization extension I was making: http://www.freelunchlabs.com/store/constant-contact-and-magento-sync.html