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); } }