Пример #1
0
 /**
  * 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);
 }
 /**
  * Set expiration reminder after the subscription gets activated
  *
  * @param int $user_id
  * @param string $subs_key
  */
 public function set_expiration_reminder($user_id, $subs_key)
 {
     $parts = explode('_', $subs_key);
     $order_id = $parts[0];
     $product_id = $parts[1];
     $order = WC_FUE_Compatibility::wc_get_order($order_id);
     $queued = array();
     if (!WC_Subscriptions_Order::order_contains_subscription($order)) {
         return;
     }
     $expiry_date = WC_Subscriptions_Manager::get_subscription_expiration_date($subs_key, $user_id);
     if (!$expiry_date) {
         return;
     }
     // convert to local time
     $expiry_timestamp = get_date_from_gmt($expiry_date, 'U');
     if (current_time('timestamp', true) > $expiry_timestamp) {
         return;
     }
     // look for renewal emails
     $emails = fue_get_emails('any', FUE_Email::STATUS_ACTIVE, array('meta_query' => array(array('key' => '_interval_type', 'value' => 'subs_before_expire'))));
     if (count($emails) > 0) {
         foreach ($emails as $email) {
             // product_id filter
             if (!empty($email->product_id) && $product_id != $email->product_id) {
                 continue;
             }
             // look for a possible duplicate item in the queue
             $dupes = Follow_Up_Emails::instance()->scheduler->get_items(array('email_id' => $email->id, 'is_sent' => 0, 'order_id' => $order_id, 'user_id' => $user_id));
             if (count($dupes) > 0) {
                 // there already is an unsent queue item for the exact same order
                 continue;
             }
             // add this email to the queue
             $interval = (int) $email->interval_num;
             $add = FUE_Sending_Scheduler::get_time_to_add($interval, $email->interval_duration);
             $send_on = $expiry_timestamp - $add;
             $insert = array('user_id' => $user_id, 'send_on' => $send_on, 'email_id' => $email->id, 'product_id' => 0, 'order_id' => $order_id);
             if ($subs_key) {
                 $insert['meta']['subs_key'] = $subs_key;
             }
             if (!is_wp_error(FUE_Sending_Scheduler::queue_email($insert, $email))) {
                 $queued[] = $insert;
             }
         }
     }
     if (count($queued) > 0) {
         $this->add_order_notes_to_queued_emails($queued);
     }
 }
 /**
  * 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');
 }
 /**
  * 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;
 }
 /**
  * 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);
         }
     }
 }
 /**
  * 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);
             }
         }
     }
 }
Пример #8
0
 /**
  * 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);
             }
         }
     }
 }
Пример #9
0
 /**
  * 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);
         }
     }
 }