public function init()
 {
     global $wpdb;
     $subscriptions_meta_key = $wpdb->get_blog_prefix() . 'woocommerce_subscriptions';
     $order_items_table = $wpdb->get_blog_prefix() . 'woocommerce_order_items';
     $order_item_meta_table = $wpdb->get_blog_prefix() . 'woocommerce_order_itemmeta';
     // Get the IDs of all users who have a subscription
     $users_to_upgrade = get_users(array('meta_key' => $subscriptions_meta_key, 'fields' => 'ID', 'orderby' => 'ID'));
     $users_to_upgrade = array_filter($users_to_upgrade, __CLASS__ . '::is_user_upgraded');
     foreach ($users_to_upgrade as $user_to_upgrade) {
         // Can't use WC_Subscriptions_Manager::get_users_subscriptions() because it relies on the new structure
         $users_old_subscriptions = get_user_option($subscriptions_meta_key, $user_to_upgrade);
         foreach ($users_old_subscriptions as $subscription_key => $subscription) {
             if (!isset($subscription['order_id'])) {
                 // Subscription created incorrectly with v1.1.2
                 continue;
             }
             $order_item_id = WC_Subscriptions_Order::get_item_id_by_subscription_key($subscription_key);
             if (empty($order_item_id)) {
                 // Subscription created incorrectly with v1.1.2
                 continue;
             }
             if (!isset($subscription['trial_expiry_date'])) {
                 $subscription['trial_expiry_date'] = '';
             }
             // Set defaults
             $failed_payments = isset($subscription['failed_payments']) ? $subscription['failed_payments'] : 0;
             $completed_payments = isset($subscription['completed_payments']) ? $subscription['completed_payments'] : array();
             $suspension_count = isset($subscription['suspension_count']) ? $subscription['suspension_count'] : 0;
             $trial_expiry_date = isset($subscription['trial_expiry_date']) ? $subscription['trial_expiry_date'] : '';
             $wpdb->query($wpdb->prepare("INSERT INTO {$order_item_meta_table} (order_item_id, meta_key, meta_value)\n\t\t\t\t\t\tVALUES\n\t\t\t\t\t\t(%d,%s,%s),\n\t\t\t\t\t\t(%d,%s,%s),\n\t\t\t\t\t\t(%d,%s,%s),\n\t\t\t\t\t\t(%d,%s,%s),\n\t\t\t\t\t\t(%d,%s,%s),\n\t\t\t\t\t\t(%d,%s,%s),\n\t\t\t\t\t\t(%d,%s,%s),\n\t\t\t\t\t\t(%d,%s,%s)", $order_item_id, '_subscription_status', $subscription['status'], $order_item_id, '_subscription_start_date', $subscription['start_date'], $order_item_id, '_subscription_expiry_date', $subscription['expiry_date'], $order_item_id, '_subscription_end_date', $subscription['end_date'], $order_item_id, '_subscription_trial_expiry_date', $trial_expiry_date, $order_item_id, '_subscription_failed_payments', $failed_payments, $order_item_id, '_subscription_completed_payments', serialize($completed_payments), $order_item_id, '_subscription_suspension_count', $suspension_count));
         }
         update_option('wcs_1_4_last_upgraded_user_id', $user_to_upgrade);
         self::$last_upgraded_user_id = $user_to_upgrade;
     }
     // Add an underscore prefix to usermeta key to deprecate, but not delete, subscriptions in user meta
     $wpdb->update($wpdb->usermeta, array('meta_key' => '_' . $subscriptions_meta_key), array('meta_key' => $subscriptions_meta_key));
     // Now set the recurring shipping & payment method on all subscription orders
     $wpdb->query("INSERT INTO {$wpdb->postmeta} (`post_id`, `meta_key`, `meta_value`)\n\t\t\tSELECT `post_id`, CONCAT('_recurring',`meta_key`), `meta_value`\n\t\t\tFROM {$wpdb->postmeta}\n\t\t\tWHERE `meta_key` IN ('_shipping_method','_shipping_method_title','_payment_method','_payment_method_title')\n\t\t\tAND `post_id` IN (\n\t\t\t\tSELECT `post_id` FROM {$wpdb->postmeta} WHERE `meta_key` = '_order_recurring_total'\n\t\t\t)");
     // Set the recurring shipping total on all subscription orders
     $wpdb->query("INSERT INTO {$wpdb->postmeta} (`post_id`, `meta_key`, `meta_value`)\n\t\t\tSELECT `post_id`, '_order_recurring_shipping_total', `meta_value`\n\t\t\tFROM {$wpdb->postmeta}\n\t\t\tWHERE `meta_key` = '_order_shipping'\n\t\t\tAND `post_id` IN (\n\t\t\t\tSELECT `post_id` FROM {$wpdb->postmeta} WHERE `meta_key` = '_order_recurring_total'\n\t\t\t)");
     // Get the ID of all orders for a subscription with a free trial and no sign-up fee
     $order_ids = $wpdb->get_col("SELECT order_items.order_id FROM {$order_items_table} AS order_items\n\t\t\t\tLEFT JOIN {$order_item_meta_table} AS itemmeta USING (order_item_id)\n\t\t\t\tLEFT JOIN {$order_item_meta_table} AS itemmeta2 USING (order_item_id)\n\t\t\tWHERE itemmeta.meta_key = '_subscription_trial_length'\n\t\t\tAND itemmeta.meta_value > 0\n\t\t\tAND itemmeta2.meta_key = '_subscription_sign_up_fee'\n\t\t\tAND itemmeta2.meta_value > 0");
     $order_ids = implode(',', array_map('absint', array_unique($order_ids)));
     // Now set the order totals to $0 (can't use $wpdb->update as it only allows joining WHERE clauses with AND)
     if (!empty($order_ids)) {
         $wpdb->query("UPDATE {$wpdb->postmeta}\n\t\t\t\tSET `meta_value` = 0\n\t\t\t\tWHERE `meta_key` IN ( '_order_total', '_order_tax', '_order_shipping_tax', '_order_shipping', '_order_discount', '_cart_discount' )\n\t\t\t\tAND `post_id` IN ( {$order_ids} )");
         // Now set the line totals to $0
         $wpdb->query("UPDATE {$order_item_meta_table}\n\t\t\t\t SET `meta_value` = 0\n\t\t\t\t WHERE `meta_key` IN ( '_line_subtotal', '_line_subtotal_tax', '_line_total', '_line_tax', 'tax_amount', 'shipping_tax_amount' )\n\t\t\t\t AND `order_item_id` IN (\n\t\t\t\t\tSELECT `order_item_id` FROM {$order_items_table}\n\t\t\t\t\tWHERE `order_item_type` IN ('tax','line_item')\n\t\t\t\t\tAND `order_id` IN ( {$order_ids} )\n\t\t\t\t)");
     }
     update_option('wcs_1_4_upgraded_order_ids', explode(',', $order_ids));
 }
 /**
  * Takes a subscription key and array of subscription details and updates the users subscription details accordingly.
  *
  * @uses wp_parse_args To allow only part of a subscription's details to be updated, like status.
  * @param string $subscription_key A subscription key of the form created by @see self::get_subscription_key()
  * @param array $new_subscription_details An array of arrays with a subscription key and corresponding 'detail' => 'value' pair. Can alter any of these details:
  *        'start_date'          The date the subscription was activated
  *        'expiry_date'         The date the subscription expires or expired, false if the subscription will never expire
  *        'failed_payments'     The date the subscription's trial expires or expired, false if the subscription has no trial period
  *        'end_date'            The date the subscription ended, false if the subscription has not yet ended
  *        'status'              Subscription status can be: cancelled, active, expired or failed
  *        'completed_payments'  An array of MySQL formatted dates for all payments that have been made on the subscription
  *        'failed_payments'     An integer representing a count of failed payments
  *        'suspension_count'    An integer representing a count of the number of times the subscription has been suspended for this billing period
  * @since 1.4
  */
 public static function update_subscription($subscription_key, $new_subscription_details)
 {
     $subscription = self::get_subscription($subscription_key);
     $item_id = WC_Subscriptions_Order::get_item_id_by_subscription_key($subscription_key);
     $item = WC_Subscriptions_Order::get_item_by_id($item_id);
     if (isset($new_subscription_details['status']) && 'deleted' == $new_subscription_details['status']) {
         woocommerce_delete_order_item($item_id);
     } else {
         $subscription_meta = array('start_date', 'expiry_date', 'trial_expiry_date', 'end_date', 'status', 'failed_payments', 'completed_payments', 'suspension_count');
         foreach ($subscription_meta as $meta_key) {
             if (isset($new_subscription_details[$meta_key]) && $new_subscription_details[$meta_key] != $subscription[$meta_key]) {
                 $subscription[$meta_key] = $new_subscription_details[$meta_key];
                 woocommerce_update_order_item_meta($item_id, '_subscription_' . $meta_key, $new_subscription_details[$meta_key]);
             }
         }
     }
     do_action('updated_users_subscription', $subscription_key, $new_subscription_details);
     return $subscription;
 }
 /**
  * Get the subscription for a membership
  *
  * @since 1.0.0
  * @param int $user_membership_id User Membership ID
  * @return array|null Subscription or null, if not found
  */
 public function get_user_membership_subscription($user_membership_id)
 {
     // 2.0 onwards
     if ($this->is_subscriptions_gte_2_0()) {
         $subscription_id = $this->get_user_membership_subscription_id($user_membership_id);
         if (!$subscription_id) {
             return null;
         }
         return wcs_get_subscription($subscription_id);
     } else {
         $subscription_key = $this->get_user_membership_subscription_key($user_membership_id);
         if (!$subscription_key) {
             return null;
         }
         $user_membership = wc_memberships_get_user_membership($user_membership_id);
         // It seems that the order has been deleted
         if (false === get_post_status($user_membership->get_order_id())) {
             return null;
         }
         // It seems the subscription product has been removed from the order
         if (!WC_Subscriptions_Order::get_item_id_by_subscription_key($subscription_key)) {
             return null;
         }
         return WC_Subscriptions_Manager::get_subscription($subscription_key);
     }
 }
 /**
  * Add email to the queue
  *
  * @param $order_id
  * @param $triggers
  * @param string $subs_key
  * @param string $user_id
  */
 public static function add_to_queue($order_id, $triggers, $subs_key = '', $user_id = '')
 {
     $emails = fue_get_emails('any', FUE_Email::STATUS_ACTIVE, array('meta_query' => array(array('key' => '_interval_type', 'value' => $triggers, 'compare' => 'IN'))));
     foreach ($emails as $email) {
         $interval = (int) $email->interval_num;
         $add = FUE_Sending_Scheduler::get_time_to_add($interval, $email->interval_duration);
         $send_on = current_time('timestamp') + $add;
         $prod_id = 0;
         if ($subs_key) {
             $item_id = WC_Subscriptions_Order::get_item_id_by_subscription_key($subs_key);
             $product_id = woocommerce_get_order_item_meta($item_id, '_product_id', true);
             $variation_id = woocommerce_get_order_item_meta($item_id, '_variation_id', true);
             $meta = maybe_unserialize($email->meta);
             $include_variations = isset($meta['include_variations']) && $meta['include_variations'] == 'yes';
             $match = false;
             // exact product match
             if ($email->product_id == $product_id) {
                 $match = true;
             } elseif ($email->product_id == $variation_id) {
                 $match = true;
             }
             if (!$match) {
                 continue;
             }
         }
         $insert = array('send_on' => $send_on, 'email_id' => $email->id, 'product_id' => $prod_id, 'order_id' => $order_id);
         if ($subs_key) {
             $insert['meta']['subs_key'] = $subs_key;
         }
         if ($user_id) {
             $user = new WP_User($user_id);
             $insert['user_id'] = $user_id;
             $insert['user_email'] = $user->user_email;
         }
         FUE_Sending_Scheduler::queue_email($insert, $email);
     }
 }