/** * Delete a queue item * * @since 4.1 * @param int $id * @return array */ public function delete_queue_item($id) { $id = $this->validate_request($id); // Return the validate error. if (is_wp_error($id)) { return $id; } do_action('fue_api_delete_queue', $id, $this); $this->scheduler->delete_item($id); $this->server->send_status('202'); return array('message' => __('Deleted queue item', 'follow_up_emails')); }
/** * Process request for sending a manual email * * @see FUE_Scheduler::queue_manual_emails */ public static function send_manual() { $post = array_map('stripslashes_deep', $_POST); $send_type = $post['send_type']; $recipients = array(); //format: array(user_id, email_address, name) if ($send_type == 'email') { $key = '0|' . $post['recipient_email'] . '|'; $recipients[$key] = array(0, $post['recipient_email'], ''); } elseif ($send_type == 'subscribers') { $subscribers = fue_get_subscribers(); foreach ($subscribers as $subscriber) { $key = '0|' . $subscriber . '|'; $recipients[$key] = array(0, $subscriber, ''); } } $recipients = apply_filters('fue_manual_email_recipients', $recipients, $post); if (!empty($recipients)) { $args = apply_filters('fue_manual_email_args', array('email_id' => $post['id'], 'recipients' => $recipients, 'subject' => $post['email_subject'], 'message' => $post['email_message'], 'tracking' => $post['tracking'], 'schedule_email' => isset($post['schedule_email']) && $post['schedule_email'] == 1 ? true : false, 'schedule_date' => $post['sending_schedule_date'], 'schedule_hour' => $post['sending_schedule_hour'], 'schedule_minute' => $post['sending_schedule_minute'], 'schedule_ampm' => $post['sending_schedule_ampm'], 'send_again' => isset($post['send_again']) && $post['send_again'] == 1 ? true : false, 'interval' => $post['interval'], 'interval_duration' => $post['interval_duration']), $post); // if the number of recipients exceed 50 and the email is set // to send immediately, use an AJAX worker to avoid timeouts if (!$args['schedule_email'] && count($recipients) > 50) { $key = $args['email_id'] . '-' . time(); set_transient('fue_manual_email_' . $key, $args, 86400); wp_redirect('admin.php?page=followup-emails&tab=send_manual_emails&key=' . $key); exit; } else { // clean up the schedule if enabled if ($args['schedule_email']) { if ($args['schedule_hour'] < 10) { $args['schedule_hour'] = '0' . $args['schedule_hour']; } if ($args['schedule_minute'] < 10) { $args['schedule_minute'] = '0' . $args['schedule_minute']; } $args['schedule_ampm'] = strtoupper($args['schedule_ampm']); } FUE_Sending_Scheduler::queue_manual_emails($args); do_action('sfn_followup_emails'); } } wp_redirect('admin.php?page=followup-emails&manual_sent=1#manual_mails'); exit; }
/** * Queue emails after an RMA's status changes * * @param int $request_id * @param string $status */ public function status_updated($request_id, $status) { global $wpdb; $order_id = get_post_meta($request_id, '_order_id', true); $triggers = array('warranty_status'); $emails = fue_get_emails('any', FUE_Email::STATUS_ACTIVE, array('meta_query' => array(array('key' => '_interval_type', 'value' => 'warranty_status')))); foreach ($emails as $email) { $interval = (int) $email->interval_num; $insert = array('send_on' => $email->get_send_timestamp(), 'email_id' => $email->id, 'user_id' => 0, 'order_id' => $order_id, 'is_cart' => 0); if (!is_wp_error(FUE_Sending_Scheduler::queue_email($insert, $email))) { // Tell FUE that an email order has been created // to stop it from sending storewide emails if (!defined('FUE_ORDER_CREATED')) { define('FUE_ORDER_CREATED', true); } } } FUE_Addon_Woocommerce::create_email_orders($triggers, $order_id); }
/** * Change the send date of the email for 'before_renewal' and 'before_expire' triggers * @param array $insert * @param FUE_Email $email * @return array */ public function modify_insert_send_date($insert, $email) { if ($email->type != 'subscription') { return $insert; } $order_id = $insert['order_id']; $order = WC_FUE_Compatibility::wc_get_order($order_id); if (!WC_Subscriptions_Order::order_contains_subscription($order)) { return $insert; } $subs_key = WC_Subscriptions_Manager::get_subscription_key($order_id); if ($email->trigger == 'subs_before_renewal') { $renewal_date = WC_Subscriptions_Manager::get_next_payment_date($subs_key); if (!$renewal_date) { // return false to tell FUE to skip importing this email/order return false; } // convert to local time $local_renewal_date = get_date_from_gmt($renewal_date, 'U'); $add = FUE_Sending_Scheduler::get_time_to_add($email->interval, $email->duration); $insert['send_on'] = $local_renewal_date - $add; } elseif ($email->trigger == 'subs_before_expire') { $expiry_date = WC_Subscriptions_Manager::get_subscription_expiration_date($subs_key); if (!$expiry_date) { return false; } // convert to local time $expiry_timestamp = get_date_from_gmt($expiry_date, 'U'); $add = FUE_Sending_Scheduler::get_time_to_add($email->interval, $email->duration); $insert['send_on'] = $expiry_timestamp - $add; } // Add the subscription key if it is not present in the meta if (!isset($insert['meta']) || empty($insert['meta']['subs_key'])) { $insert['meta']['subs_key'] = $subs_key; } return $insert; }
/** * AJAX handler to start email import */ public static function scheduler_do_import() { $next = $_POST['next']; $next = FUE_Sending_Scheduler::action_scheduler_import($next, 50); $usage = memory_get_usage(true); $limit = ini_get('memory_limit'); if ($usage < 1024) { $usage = $usage . " bytes"; } elseif ($usage < 1048576) { $usage = round($usage / 1024, 2) . " kilobytes"; } else { $usage = round($usage / 1048576, 2) . " megabytes"; } die(json_encode(array('next' => $next, 'usage' => $usage, 'limit' => $limit))); }
/** * Add manual emails to the email queue * * $args keys: * email_id - ID of FUE_Email * recipients - Array of recipients ( format: [ [user_id, user_email, user_name] ] ) * subject - Email Subject * message - Email Message * tracking - Analytics tracking code (e.g. ?utm_campaign=xxx) * send_again - Whether or not to send another email after a specific interval (bool) * interval - If send_again is true, the time to wait before sending the next email (int) * interval_duration - If send_again is true, the duration type of interval (e.g. minutes/hours/weeks/months) * * @param array $args * @return array Array of Queue Item IDs created */ public static function queue_manual_emails($args = array()) { ignore_user_abort(true); set_time_limit(0); $item_ids = array(); $args = wp_parse_args($args, array('email_id' => 0, 'recipients' => array(), 'subject' => '', 'message' => '', 'tracking' => '', 'schedule_email' => false, 'schedule_date' => '', 'schedule_hour' => '', 'schedule_minute' => '', 'schedule_ampm' => '', 'send_again' => false, 'interval' => '', 'interval_duration' => '')); extract($args); if (empty($recipients)) { return; } // process variable replacements $codes = array(); if (!empty($tracking)) { parse_str($tracking, $codes); foreach ($codes as $key => $val) { $codes[$key] = urlencode($val); } } $store_url = home_url(); $store_name = get_bloginfo('name'); $orig_message = $message; $orig_subject = $subject; $recipient_num = 0; $send_time = current_time('timestamp'); $email = new FUE_Email($email_id); $email_batch_enabled = get_option('fue_email_batches', 0); $emails_per_batch = get_option('fue_emails_per_batch', 100); $email_batch_interval = get_option('fue_batch_interval', 10); $schedule_emails = false; // figure out the sending schedule if ($schedule_email) { $send_time = strtotime($schedule_date . ' ' . $schedule_hour . ':' . $schedule_minute . ' ' . $schedule_ampm); $schedule_emails = true; } // if splitting emails into batches is enabled and more than one // batch is going to be queued, schedule the emails if ($email_batch_enabled && count($recipients) > $emails_per_batch) { $schedule_emails = true; } foreach ($recipients as $recipient) { $recipient_num++; // determine when to send this email if (1 == $email_batch_enabled) { if ($recipient_num == $emails_per_batch) { $send_time += $email_batch_interval * 60; $recipient_num = 0; } } // create an email order $user_id = $recipient[0]; $email_address = $recipient[1]; $user_name = $recipient[2]; $unsubscribe = add_query_arg('fue', $email_address, fue_get_unsubscribe_url()); $_message = $orig_message; $_subject = $orig_subject; $meta = array('recipient' => $recipient, 'user_id' => $recipient[0], 'email_address' => $recipient[1], 'user_name' => $recipient[2], 'subject' => $_subject, 'message' => $_message, 'codes' => $codes); $insert = array('user_id' => $user_id, 'email_id' => $email_id, 'user_email' => $email_address, 'send_on' => $send_time, 'email_trigger' => 'Manual Email', 'meta' => $meta); $queue_id = FUE_Sending_Scheduler::queue_email($insert, $email, $schedule_emails); if (!is_wp_error($queue_id)) { $item_ids[] = $queue_id; } if ($send_again && !empty($interval) && $interval > 0) { $add = FUE_Sending_Scheduler::get_time_to_add($interval, $interval_duration); // create an email order $email_data = array('user_id' => $user_id, 'email_id' => $email_id, 'user_email' => $email_address, 'send_on' => $send_time + $add, 'email_trigger' => 'Manual Email', 'meta' => serialize($meta)); $queue_id = FUE_Sending_Scheduler::queue_email($email_data, $email, true); if (!is_wp_error($queue_id)) { $item_ids[] = $queue_id; } } } return $item_ids; }
/** * Import orders that match the given $email * @param FUE_Email $email * @param int $limit The maximum number of orders to import per run * @return array */ public function import_orders_for_email($email, $limit = 100) { $orders = get_transient('fue_orders_for_email_' . $email->id); //$orders = array_slice( $this->get_orders_for_email( $email ), 0, $limit ); $imported = array(); $processed = 0; foreach ($orders as $idx => $order_id) { $processed++; // break out of the loop if the $limit has been hit if ($processed > $limit) { break; } // remove from $orders so this doesn't get processed again in the next run unset($orders[$idx]); if (!$order_id) { $imported[] = array('id' => $order_id, 'status' => 'failed', 'reason' => sprintf(__('Importing failed. Invalid order (#%d)', 'follow_up_emails'), $order_id)); continue; } $order = WC_FUE_Compatibility::wc_get_order($order_id); $start_date = null; if ($email->trigger == 'first_purchase') { $start_date = $order->post->post_date; } $insert = apply_filters('fue_wc_import_insert', array('send_on' => $email->get_send_timestamp($start_date), 'email_id' => $email->id, 'order_id' => $order_id, 'user_id' => $order->customer_user, 'user_email' => $order->billing_email), $email); if ($insert) { $item_id = FUE_Sending_Scheduler::queue_email($insert, $email); if (is_wp_error($item_id)) { $imported[] = array('id' => $order_id, 'status' => 'failed', 'reason' => sprintf(__('Importing failed. %s', 'follow_up_emails'), $item_id->get_error_message())); continue; } $_order = WC_FUE_Compatibility::wc_get_order($order_id); $email_trigger = apply_filters('fue_interval_str', $email->get_trigger_string(), $email); $send_date = date(get_option('date_format') . ' ' . get_option('time_format'), $email->get_send_timestamp()); if ($_order) { $note = sprintf(__('Email queued: %s scheduled on %s<br/>Trigger: %s', 'follow_up_emails'), $email->name, $send_date, $email_trigger); $_order->add_order_note($note); $imported[] = array('id' => $order_id, 'status' => 'success'); } else { $imported[] = array('id' => $order_id, 'status' => 'failed', 'reason' => sprintf(__('Importing failed. Could not load order (#%d)', 'follow_up_emails'), $order_id)); } } } if (count($orders) > 0) { // store the new $orders array set_transient('fue_orders_for_email_' . $email->id, $orders, 600); } else { // completed. delete the transient delete_transient('fue_orders_for_email_' . $email->id); } return array('imported' => $imported, 'remaining_orders' => count($orders), 'status' => count($orders) > 0 ? 'running' : 'completed'); }
/** * Schedule the daily summary recurring emails */ public function init_daily_summary() { if (!function_exists('wc_next_scheduled_action')) { return; } if (wc_next_scheduled_action('fue_send_summary')) { wc_unschedule_action('fue_send_summary'); } FUE_Sending_Scheduler::queue_daily_summary_email(); delete_option('fue_init_daily_summary'); }
/** * Queue reminder emails * * @param WC_Order $order * @return array */ public function queue_reminder_emails($order) { $queued = array(); $item_ids = $this->get_product_ids_from_order($order); $triggers = $this->get_order_triggers($order, Follow_Up_Emails::get_email_type('reminder')); $product_ids = array(); $variation_ids = array(); foreach ($item_ids as $item_id) { $product_ids[] = $item_id['product_id']; if ($item_id['variation_id']) { $variation_ids[] = $item_id['variation_id']; } } $product_ids = array_merge(array_unique($product_ids), array_unique($variation_ids)); $args = array('meta_query' => array('relation' => 'AND', array('key' => '_interval_type', 'value' => $triggers, 'compare' => 'IN'))); $emails = fue_get_emails('reminder', FUE_Email::STATUS_ACTIVE, $args); foreach ($emails as $email) { if ($email->product_id > 0 && !in_array($email->product_id, $product_ids)) { // Product ID does not match continue; } $queue_items = Follow_Up_Emails::instance()->scheduler->get_items(array('order_id' => $order->id, 'email_id' => $email->id)); // only queue reminders once per order and email if (count($queue_items) == 0) { $interval = $email->interval; $interval_duration = $email->interval_duration; // get the item's quantity $qty = 0; $num_products = false; foreach ($order->get_items() as $item) { $variation_id = $item['variation_id']; $item_id = $item['product_id']; if ($email->product_id == 0 || ($item_id == $email->product_id || $variation_id == $email->product_id)) { $qty = $item['qty']; if (isset($item['item_meta']) && !empty($item['item_meta'])) { foreach ($item['item_meta'] as $meta_key => $meta_value) { if ($meta_key == 'Filters/Case') { $num_products = $meta_value[0]; break; } } } } } // look for a lifespan product variable $lifespan = get_post_meta($email->product_id, 'filter_lifespan', true); if ($lifespan && $lifespan > 0) { $interval = (int) $lifespan; $interval_duration = 'months'; } if ($num_products !== false && $num_products > 0) { $qty = $qty * $num_products; } if ($qty == 1) { // only send the first email $add = FUE_Sending_Scheduler::get_time_to_add($interval, $interval_duration); $send_on = current_time('timestamp') + $add; $insert = array('send_on' => $send_on, 'email_id' => $email->id, 'product_id' => $email->product_id, 'order_id' => $order->id); if (!is_wp_error(FUE_Sending_Scheduler::queue_email($insert, $email))) { $queued[] = $insert; } } elseif ($qty == 2) { // only send the first and last emails $add = FUE_Sending_Scheduler::get_time_to_add($interval, $interval_duration); $send_on = current_time('timestamp') + $add; $insert = array('send_on' => $send_on, 'email_id' => $email->id, 'product_id' => $email->product_id, 'order_id' => $order->id); if (!is_wp_error(FUE_Sending_Scheduler::queue_email($insert, $email))) { $queued[] = $insert; } $last = FUE_Sending_Scheduler::get_time_to_add($interval, $interval_duration); $send_on = current_time('timestamp') + $add + $last; $insert = array('send_on' => $send_on, 'email_id' => $email->id, 'product_id' => $email->product_id, 'order_id' => $order->id); if (!is_wp_error(FUE_Sending_Scheduler::queue_email($insert, $email))) { $queued[] = $insert; } } else { // send all emails $add = FUE_Sending_Scheduler::get_time_to_add($interval, $interval_duration); $last = 0; for ($x = 1; $x <= $qty; $x++) { $send_on = current_time('timestamp') + $add + $last; $last += $add; $insert = array('send_on' => $send_on, 'email_id' => $email->id, 'product_id' => $email->product_id, 'order_id' => $order->id); if (!is_wp_error(FUE_Sending_Scheduler::queue_email($insert, $email))) { $queued[] = $insert; } } } } } return $queued; }
/** * Get the timestamp when the email will be sent that is relative to the current date/time * @param string $start_date The date to base the calculation on. Leave empty to use the current date * * @return int */ public function get_send_timestamp($start_date = null) { $send_on = 0; if ($this->interval_type == 'date') { if (!empty($this->send_date_hour) && !empty($this->send_date_minute)) { $send_on = strtotime($this->send_date . ' ' . $this->send_date_hour . ':' . $this->send_date_minute); if (false === $send_on) { // fallback to only using the date $send_on = strtotime($this->send_date); } } else { $send_on = strtotime($this->send_date); } } else { $add = FUE_Sending_Scheduler::get_time_to_add($this->interval_num, $this->interval_duration); if (!is_null($start_date)) { $time_from = strtotime($start_date); } else { $time_from = current_time('timestamp'); } $send_on = $time_from + $add; } return $send_on; }
/** * Queue emails after an order is marked as completed * @param int $order_id */ public function set_reminders($order_id) { global $woocommerce, $wpdb; // load reminder emails $emails = fue_get_emails('wootickets', FUE_Email::STATUS_ACTIVE, array('meta_query' => array(array('key' => '_interval_type', 'value' => array('before_tribe_event_starts', 'after_tribe_event_ends'), 'compare' => 'IN')))); $tickets = array(); if (empty($emails)) { return; } $has_tickets = get_post_meta($order_id, '_tribe_has_tickets', true); $order = WC_FUE_Compatibility::wc_get_order($order_id); $items = $order->get_items(); foreach ($items as $item) { $ticket_id = isset($item['id']) ? $item['id'] : $item['product_id']; // if $item is a ticket, load the event where the ticket is attached to $event_id = get_post_meta($ticket_id, '_tribe_wooticket_for_event', true); if (!$event_id) { continue; } if (!in_array($ticket_id, $tickets)) { $tickets[] = $ticket_id; } } $now = current_time('timestamp'); foreach ($emails as $email) { $interval = (int) $email->interval_num; $add = FUE_Sending_Scheduler::get_time_to_add($interval, $email->interval_duration); foreach ($tickets as $ticket_id) { // if this email is for a specific ticket, make sure the IDs match if (!empty($email->product_id) && $email->product_id != $ticket_id) { continue; } // check for category matching if (!empty($email->category_id)) { $ticket_terms = get_the_terms($ticket_id, 'product_cat'); $product_categories = array(); if ($ticket_terms && !is_wp_error($ticket_terms)) { foreach ($ticket_terms as $ticket_term) { $product_categories[$ticket_term->term_id] = $ticket_term->name; } } if (!array_key_exists($email->category_id, $product_categories)) { continue; } } $event_id = get_post_meta($ticket_id, '_tribe_wooticket_for_event', true); if ($email->interval_type == 'before_tribe_event_starts') { $start = get_post_meta($event_id, '_EventStartDate', true); if (empty($start)) { continue; } $start = strtotime($start); // check if a limit is in place $email_meta = maybe_unserialize($email->meta); if (isset($email_meta['tribe_limit'], $email_meta['tribe_limit_days']) && !empty($email_meta['tribe_limit_days'])) { $days = ($start - $now) / 86400; if ($days <= $email_meta['tribe_limit_days']) { // $days is within limit - skip continue; } } $send_on = $start - $add; // if send_on is in the past, do not queue it if ($now > $send_on) { continue; } } else { $end = get_post_meta($event_id, '_EventEndDate', true); if (empty($end)) { continue; } $end = strtotime($end); $send_on = $end + $add; // if send_on is in the past, do not queue it if ($now > $send_on) { continue; } } $insert = array('user_id' => $order->user_id, 'order_id' => $order_id, 'product_id' => $ticket_id, 'email_id' => $email->id, 'send_on' => $send_on); FUE_Sending_Scheduler::queue_email($insert, $email); } } }
/** * Process a specific item from the queue * * @param FUE_Sending_Queue_Item $queue_item A row from wp_followup_email_orders * @return bool|WP_Error TRUE if the email was sent or a WP_Error object if an error occured */ public function send_queue_item($queue_item) { $wpdb = Follow_Up_Emails::instance()->wpdb; // if a queue item doesn't have an email_id, it needs to have either a // subscription_notification or daily_summary meta key if (empty($queue_item->email_id)) { if (isset($queue_item->meta['subscription_notification']) || isset($queue_item->meta['daily_summary'])) { return $this->send_adhoc_email($queue_item); } else { // invalid queue item. delete! Follow_Up_Emails::instance()->scheduler->delete_item($queue_item->id); return new WP_Error('fue_queue_error', __('Queue item deleted because no email was assigned to it', 'follow_up_emails')); } } // only process unsent email orders if ($queue_item->is_sent != 0) { return new WP_Error('fue_queue_error', __('Queue item has already been sent', 'follow_up_emails')); } $email = new FUE_Email($queue_item->email_id); // make sure that the email is not disabled if ($email->status != FUE_Email::STATUS_ACTIVE && $email->type != 'manual') { return new WP_Error('fue_queue_error', __('Could not send email because it is not active', 'follow_up_emails')); } // set local variables $this->email = $email; $this->queue = $queue_item; // email cannot be active and have an empty message if (empty($email->message)) { // set the status to inactive $email->update_status(FUE_Email::STATUS_INACTIVE); return new WP_Error('fue_queue_error', __('Cannot send emails without a message. Email has been deactivated', 'follow_up_emails')); } // if the queue item is cron locked, reschedule to avoid duplicate emails being sent if (FUE_Sending_Scheduler::is_queue_item_locked($queue_item)) { FUE_Sending_Scheduler::reschedule_queue_item($queue_item); return new WP_Error('fue_queue_notice', __('This email is locked due to a previous attempt in sending the email. Sending has been rescheduled to avoid duplicate emails.', 'follow_up_emails')); } // place a cron lock to prevent duplicates FUE_Sending_Scheduler::lock_email_queue($queue_item); $email_data = $this->get_email_data($queue_item, $email); // remove from queue if the user chose to not receive emails // non-order related emails if ($queue_item->user_id > 0 && $queue_item->order_id == 0 && fue_user_opted_out($queue_item->user_id)) { Follow_Up_Emails::instance()->scheduler->delete_item($queue_item->id); return new WP_Error('fue_queue_notice', __('The customer opted out of recieving non-order related emails. Email has been deleted.', 'follow_up_emails')); } // do not send if the recipient's email is on the excludes list if (fue_is_email_excluded($email_data['email_to']) || $queue_item->order_id > 0 && fue_is_email_excluded($email_data['email_to'], 0, $queue_item->order_id)) { do_action('fue_email_excluded', $email_data['email_to'], $queue_item->id); Follow_Up_Emails::instance()->scheduler->delete_item($queue_item->id); return new WP_Error('fue_queue_notice', __('The customer is on the "Exclude Emails" list. Email deleted.', 'follow_up_emails')); } // allow other extensions to "skip" sending this email $skip = apply_filters('fue_skip_email_sending', false, $email, $queue_item); if ($skip) { return new WP_Error('fue_queue_notice', __('An add-on has marked this email to be skipped.', 'follow_up_emails')); } $email_data['subject'] = apply_filters('fue_email_subject', $email_data['subject'], $email, $queue_item); $email_data['message'] = apply_filters('fue_email_message', $email_data['message'], $email, $queue_item); $email_data = $this->process_variable_replacements($email_data); // hook to variable replacement $email_data['subject'] = apply_filters('fue_send_email_subject', $email_data['subject'], $queue_item); $email_data['message'] = apply_filters('fue_send_email_message', $email_data['message'], $queue_item); $email_data['message'] = $this->process_link_variables($email_data, $queue_item, $email); $headers = apply_filters('fue_email_headers', array($this->get_bcc_header(), $this->get_reply_to_header()), $email, $queue_item); add_filter('wp_mail_from', array($this, 'get_wp_email_from'), 20); add_filter('wp_mail_from_name', array($this, 'get_wp_email_from_name'), 20); // send the email do_action('fue_before_email_send', $email_data['subject'], $email_data['message'], $headers, $queue_item); // Decode html entities to UTF-8 (http://php.net/html_entity_decode#104617) if (function_exists('mb_convert_encoding')) { $email_data['subject'] = preg_replace_callback("/(&#[0-9]+;)/", array($this, 'convert_encoding'), $email_data['subject']); } // apply the email template if (!empty($email->template)) { $email_data['message'] = $email->apply_template($email_data['message']); } // allow plugins to take care of the sending // plugins that override the sending must return TRUE to stop FUE from sending this queue item $sent = apply_filters('fue_send_queue_item', false, $queue_item, $email_data, $headers); // return if an error occured if (is_wp_error($sent)) { return $sent; } if (!$sent) { $email_data = apply_filters('fue_before_sending_email', $email_data, $email, $queue_item); self::mail($email_data['email_to'], $email_data['subject'], $email_data['message'], $headers); } do_action('fue_after_email_sent', $email_data['subject'], $email_data['message'], $headers, $queue_item); $this->log_sent_email($email_data); // increment usage count fue_update_email(array('id' => $email->id, 'usage_count' => $email->usage_count + 1)); // update the email order $now = get_date_from_gmt(date('Y-m-d H:i:s'), 'Y-m-d H:i:s'); $wpdb->update($wpdb->prefix . 'followup_email_orders', array('is_sent' => 1, 'date_sent' => $now, 'email_trigger' => $email->get_trigger_string()), array('id' => $queue_item->id)); do_action('fue_email_order_sent', $queue_item->id); do_action('fue_email_sent_details', $queue_item, $queue_item->user_id, $email, $email_data['email_to'], $email_data['cname'], $email->get_trigger_string()); // remove queue lock FUE_Sending_Scheduler::remove_queue_item_lock($queue_item); // if this is a 'date' email and there are no more unsent emails // of the same kind in the queue, archive it self::maybe_archive_email($email); return true; }
/** * Action fired after points have been increased * * @param int $user_id * @param int $points * @param string $event_type * @param array $data * @param int $order_id */ public function after_points_increased($user_id, $points, $event_type, $data = null, $order_id = 0) { $emails = fue_get_emails('points_and_rewards', FUE_Email::STATUS_ACTIVE, array('meta_query' => array(array('key' => '_interval_type', 'value' => array('points_earned', 'points_greater_than'), 'compare' => 'IN')))); foreach ($emails as $email) { if ($email->interval_type == 'points_greater_than') { $meta = maybe_unserialize($email->meta); if ($points < $meta['points_greater_than']) { continue; } } $insert = array('send_on' => $email->get_send_timestamp(), 'email_id' => $email->id, 'user_id' => $user_id, 'order_id' => $order_id, 'is_cart' => 0); $email_order_id = FUE_Sending_Scheduler::queue_email($insert, $email); if (!is_wp_error($email_order_id)) { $data = array('user_id' => $user_id, 'points' => $points, 'event_type' => $event_type); update_option('fue_email_order_' . $email_order_id, $data); // Tell FUE that an email order has been created // to stop it from sending storewide emails if (!defined('FUE_ORDER_CREATED')) { define('FUE_ORDER_CREATED', true); } } } }
/** * Send emails that matches the provided triggers to the queue * @param int $booking_id * @param array $triggers */ private function create_email_order($booking_id, $triggers = array()) { /** * @var $booking WC_Booking * @var $order WC_Order */ $booking = get_wc_booking($booking_id); $last_status = get_post_meta($booking_id, '_last_status', true); $order = WC_FUE_Compatibility::wc_get_order($booking->order_id); $emails = fue_get_emails('wc_bookings', FUE_Email::STATUS_ACTIVE, array('meta_query' => array(array('key' => '_interval_type', 'value' => $triggers, 'compare' => 'IN')))); foreach ($emails as $email) { if (!empty($email->meta['bookings_last_status']) && $email->meta['bookings_last_status'] != $last_status) { continue; } if ($this->is_category_excluded($booking, $email)) { continue; } // A booking can have no order linked to it if ($order) { $customer = fue_get_customer_from_order($order); if (Follow_Up_Emails::instance()->fue_wc->wc_scheduler->exclude_customer_based_on_purchase_history($customer, $email)) { continue; } } if ($email->interval_type == 'before_booking_event') { $start = strtotime(get_post_meta($booking_id, '_booking_start', true)); $time = FUE_Sending_Scheduler::get_time_to_add($email->interval_num, $email->interval_duration); $send_on = $start - $time; } elseif ($email->interval_type == 'after_booking_event') { $start = strtotime(get_post_meta($booking_id, '_booking_end', true)); $time = FUE_Sending_Scheduler::get_time_to_add($email->interval_num, $email->interval_duration); $send_on = $start + $time; } else { $send_on = $email->get_send_timestamp(); } $insert = array('send_on' => $send_on, 'email_id' => $email->id, 'product_id' => $booking->product_id, 'order_id' => $booking->order_id, 'meta' => array('booking_id' => $booking_id)); if ($order) { $user_id = WC_FUE_Compatibility::get_order_user_id($order); if ($user_id) { $user = new WP_User($user_id); $insert['user_id'] = $user_id; $insert['user_email'] = $user->user_email; } } // Remove the nonce to avoid infinite loop because doing a // remove_action on WC_Bookings_Details_Meta_Box doesnt work unset($_POST['wc_bookings_details_meta_box_nonce']); if (!is_wp_error(FUE_Sending_Scheduler::queue_email($insert, $email))) { // Tell FUE that an email order has been created // to stop it from sending storewide emails if (!defined('FUE_ORDER_CREATED')) { define('FUE_ORDER_CREATED', true); } } } }
/** * Fired everytime an email is sent, check to make sure that there * is a scheduled daily summary email in the queue. */ public function register_action_scheduler_for_daily_summary() { $items = Follow_Up_Emails::instance()->scheduler->get_items(array('is_sent' => 0, 'email_trigger' => 'Daily Summary')); if (empty($items)) { // there are no unsent daily_summary emails in the queue FUE_Sending_Scheduler::queue_daily_summary_email(); } else { $scheduled = false; foreach ($items as $item) { $param = array('email_order_id' => $item->id); $actions = wc_get_scheduled_actions(array('hook' => 'sfn_followup_emails', 'args' => $param, 'status' => ActionScheduler_Store::STATUS_PENDING)); if (!empty($actions)) { $scheduled = true; break; } } if (!$scheduled) { FUE_Sending_Scheduler::queue_daily_summary_email(); } } }
/** * Check if a specific answer has been submitted * * @param array $args * @param array $data */ public function check_for_answer($args, $data) { global $wpdb; if ($args['type'] != 'sensei_user_answer') { return; } $question_id = $args['post_id']; $emails = fue_get_emails('sensei', FUE_Email::STATUS_ACTIVE, array('meta_query' => array(array('key' => '_interval_type', 'value' => 'specific_answer')))); foreach ($emails as $email) { $meta = maybe_unserialize($email->meta); if (is_array($meta)) { $email_question_id = isset($meta['sensei_question_id']) ? $meta['sensei_question_id'] : ''; $email_answer = isset($meta['sensei_answer']) ? $meta['sensei_answer'] : ''; // The answer to check for is required if (empty($email_answer)) { continue; } // Question IDs must match if ($email_question_id != $question_id) { continue; } $posted_answer = maybe_unserialize(base64_decode($args['data'])); // answers do not match if (is_array($posted_answer)) { $posted_answer = current($posted_answer); } if ($email_answer != $posted_answer) { continue; } $values = array('user_id' => $args['user_id'], 'meta' => array('question_id' => $question_id, 'answer' => $posted_answer)); FUE_Sending_Scheduler::queue_email($values, $email); } } }